﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ПрограммныйИнтерфейс

////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для стандартной обработки свойств.

// Создает основные реквизиты и поля формы, необходимые для работы.
// Заполняет дополнительные реквизиты, если используются.
// Вызывается из обработчика ПриСозданииНаСервере формы объекта со свойствами.
// 
// Параметры:
//  Форма - ФормаКлиентскогоПриложения - в которой будут отображаться дополнительные реквизиты со свойствами:
//    * Объект - ДанныеФормыСтруктура - по типу объекта, со свойствами:
//      ** Ссылка - ЛюбаяСсылка - ссылка на объект, к которому подключаются свойства.
//
//  ДополнительныеПараметры - Неопределено - все дополнительные параметры имеют значения по умолчанию.
//                               Ранее реквизит назывался "Объект" и имел смысл,
//                               как одноименное свойство структуры, указанной ниже.
//                          - Структура - с необязательными свойствами:
//
//    * Объект - ДанныеФормыСтруктура - по типу объекта, содержит свойства:
//      ** Ссылка - ЛюбаяСсылка - ссылка на объект, к которому подключаются свойства.
//
//    * ИмяЭлементаДляРазмещения - Строка - имя группы формы, в которой будут размещены свойства.
//
//    * ПроизвольныйОбъект - Булево - если Истина, тогда в форме создается таблица описания дополнительных
//            реквизитов, параметр Объект игнорируется, дополнительные реквизиты не создаются и не заполняются.
//
//            Это востребовано при последовательном использовании одной формы для просмотра или редактирования
//            дополнительных реквизитов разных объектов (в том числе разных типов).
//
//            После выполнения ПриСозданииНаСервере следует вызывать ЗаполнитьДополнительныеРеквизитыВФорме()
//            для добавления и заполнения дополнительных реквизитов.
//            Чтобы сохранить изменения, следует вызвать ПеренестиЗначенияИзРеквизитовФормыВОбъект(),
//            а для обновления состава реквизитов вызвать ОбновитьЭлементыДополнительныхРеквизитов().
//
//    * ИмяЭлементаКоманднойПанели - Строка - имя группы формы, в которую будет добавлена кнопка.
//            РедактироватьСоставДополнительныхРеквизитов. Если имя элемента не указано,
//            используется стандартная группа "Форма.КоманднаяПанель".
//
//    * СкрытьУдаленные - Булево - установить/отключить режим скрытия удаленных.
//            Если параметр не указан, а параметр Объект указан и свойство Ссылка не заполнено,
//            тогда начальное значение устанавливается Истина, иначе Ложь.
//            При вызове процедуры ПередЗаписьюНаСервере в режиме скрытия удаленных удаленные значения
//            очищаются (не переносятся обратно в объект), а режим СкрытьУдаленные устанавливается Ложь.
//
//    * ПараметрыОтображенияМеток - см. ПараметрыОтображенияМеток.
//
Процедура ПриСозданииНаСервере(Форма, ДополнительныеПараметры = Неопределено) Экспорт
	
	Если Не ИспользуютсяСвойства(Форма, ДополнительныеПараметры) Тогда
		Возврат;
	КонецЕсли;
	
	Контекст = Новый Структура;
	Контекст.Вставить("Объект",                     Неопределено);
	Контекст.Вставить("ИмяЭлементаДляРазмещения",   "");
	Контекст.Вставить("ОтложеннаяИнициализация",    Ложь);
	Контекст.Вставить("ПроизвольныйОбъект",         Ложь);
	Контекст.Вставить("ИмяЭлементаКоманднойПанели", "");
	Контекст.Вставить("СкрытьУдаленные",            Неопределено);
	Контекст.Вставить("ПараметрыОтображенияМеток",  ПараметрыОтображенияМеток());
	
	Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
		ЗаполнитьЗначенияСвойств(Контекст, ДополнительныеПараметры);
	КонецЕсли;
	
	Если Контекст.ПроизвольныйОбъект Тогда
		СоздатьОписаниеДополнительныхРеквизитов = Истина;
	Иначе
		Если Контекст.Объект = Неопределено Тогда
			ОписаниеОбъекта = Форма.Объект;
		Иначе
			ОписаниеОбъекта = Контекст.Объект;
		КонецЕсли;
		СоздатьОписаниеДополнительныхРеквизитов = ИспользоватьДопРеквизиты(ОписаниеОбъекта.Ссылка);
		Если Не ЗначениеЗаполнено(ОписаниеОбъекта.Ссылка) И Контекст.СкрытьУдаленные = Неопределено Тогда
			Контекст.СкрытьУдаленные = Истина;
		КонецЕсли;
	КонецЕсли;
	
	СоздатьОсновныеОбъектыФормы(Форма, Контекст, СоздатьОписаниеДополнительныхРеквизитов);
	
	Если Контекст.ОтложеннаяИнициализация Тогда
		
		Если НЕ Форма.Свойства_ИспользоватьСвойства
			ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
			Возврат;
		КонецЕсли;
		
		КлючНазначения = Неопределено;
		НаборыСвойствОбъекта = УправлениеСвойствамиСлужебный.ПолучитьНаборыСвойствОбъекта(
			ОписаниеОбъекта, КлючНазначения);
		
		УправлениеСвойствамиСлужебный.ЗаполнитьНаборыСДополнительнымиРеквизитами(
			НаборыСвойствОбъекта,
			Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
		
		ОтображатьЗакладку = УправлениеСвойствамиСлужебный.ОтображатьЗакладкуДополнительно(
			ОписаниеОбъекта.Ссылка, Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
		
		Если Форма.ПараметрыСвойств.Свойство("ДобавленаПустаяДекорация") Тогда
			Для Каждого ИмяДекорации Из Форма.ПараметрыСвойств.КоллекцияДекораций Цикл
				Форма.Элементы[ИмяДекорации].Видимость = ОтображатьЗакладку;
			КонецЦикла;
		КонецЕсли;
		
		ОбновитьКлючНазначенияФормы(Форма, КлючНазначения);
	КонецЕсли;
	
	Если Не Контекст.ПроизвольныйОбъект
		И Не Контекст.ОтложеннаяИнициализация Тогда
		ЗаполнитьДополнительныеРеквизитыВФорме(Форма, ОписаниеОбъекта, , Контекст.СкрытьУдаленные);
	КонецЕсли;
	
	УстановитьВидимостьМеток(Форма, Контекст.ПараметрыОтображенияМеток.ИмяЭлементаДляРазмещенияМеток);
	ЗаполнитьМеткиОбъекта(Форма, ОписаниеОбъекта, Контекст.ПроизвольныйОбъект);
	Если Контекст.ПроизвольныйОбъект Тогда
		ЗаполнитьЛегендуМеток(Форма, ОписаниеОбъекта);
	КонецЕсли;
	
КонецПроцедуры

// Заполняет объект из реквизитов, созданных в форме.
// Вызывается из обработчика ПередЗаписьюНаСервере формы объекта со свойствами.
//
// Параметры:
//  Форма         - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//  ТекущийОбъект - СправочникОбъектИмяСправочника
//                - ДокументОбъектИмяДокумента
//                - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                - БизнесПроцессОбъектИмяБизнесПроцесса
//                - ЗадачаОбъектИмяЗадачи
//                - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                - ПланСчетовОбъектИмяПланаСчетов
//
Процедура ПриЧтенииНаСервере(Форма, ТекущийОбъект) Экспорт
	
	Структура = Новый Структура("Свойства_ИспользоватьСвойства");
	ЗаполнитьЗначенияСвойств(Структура, Форма);
	
	Если ТипЗнч(Структура.Свойства_ИспользоватьСвойства) = Тип("Булево")
		И Структура.Свойства_ИспользоватьСвойства Тогда
		
		Если Форма.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация")
			И Не Форма.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация Тогда
			Возврат;
		КонецЕсли;
		
		ЗаполнитьДополнительныеРеквизитыВФорме(Форма, ТекущийОбъект);
	КонецЕсли;
	
КонецПроцедуры

// Заполняет объект из реквизитов, созданных в форме.
// Вызывается из обработчика ПередЗаписьюНаСервере формы объекта со свойствами.
//
// Параметры:
//  Форма         - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//  ТекущийОбъект - СправочникОбъектИмяСправочника
//                - ДокументОбъектИмяДокумента
//                - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                - БизнесПроцессОбъектИмяБизнесПроцесса
//                - ЗадачаОбъектИмяЗадачи
//                - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                - ПланСчетовОбъектИмяПланаСчетов
//
Процедура ПередЗаписьюНаСервере(Форма, ТекущийОбъект) Экспорт
	
	УправлениеСвойствамиСлужебный.ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, ТекущийОбъект, Истина);
	
КонецПроцедуры

// Проверяет заполненность реквизитов, обязательных для заполнения.
// 
// Параметры:
//  Форма - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере со свойствами:
//     * Свойства_ОписаниеДополнительныхРеквизитов - ТаблицаЗначений:
//        ** ИмяРеквизитаЗначение - Строка
//        ** Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
//        ** ВладелецДополнительныхЗначений - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
//        ** ТипЗначения - ОписаниеТипов
//        ** МногострочноеПолеВвода - Число
//        ** Удалено - Булево
//        ** ЗаполнятьОбязательно - Булево
//        ** Доступен - Булево
//        ** Виден - Булево
//        ** Наименование - Строка
//        ** ЭлементФормыДобавлен - Булево
//        ** ВыводитьВВидеГиперссылки - Булево
//        ** СтрокаСсылочногоТипа - Булево
//  Отказ                - Булево - параметр обработчика ОбработкаПроверкиЗаполненияНаСервере.
//  ПроверяемыеРеквизиты - Массив - параметр обработчика ОбработкаПроверкиЗаполненияНаСервере.
//  Объект        - СправочникОбъектИмяСправочника
//                - ДокументОбъектИмяДокумента
//                - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                - БизнесПроцессОбъектИмяБизнесПроцесса
//                - ЗадачаОбъектИмяЗадачи
//                - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                - ПланСчетовОбъектИмяПланаСчетов
//                - Неопределено - если свойство не указано или Неопределено,
//                                 объект берется из реквизита формы "Объект". 
//
Процедура ОбработкаПроверкиЗаполнения(Форма, Отказ, ПроверяемыеРеквизиты, Объект = Неопределено) Экспорт
	
	ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияСвойств = Истина;
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
	 ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		
		Возврат;
	КонецЕсли;
	
	Приемник = Новый Структура;
	Приемник.Вставить("ПараметрыСвойств", Неопределено);
	ЗаполнитьЗначенияСвойств(Приемник, Форма);
	
	Если ТипЗнч(Приемник.ПараметрыСвойств) = Тип("Структура")
		И Приемник.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация")
		И Не Приемник.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация Тогда
		ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект);
	КонецЕсли;
	
	Для каждого Строка Из Форма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		Если Строка.ЗаполнятьОбязательно И НЕ Строка.Удалено Тогда
			Если Не РеквизитДоступенПоФункциональнымОпциям(Строка) Тогда
				Продолжить;
			КонецЕсли;
			Результат = Истина;
			Если Объект = Неопределено Тогда
				ОписаниеОбъекта = Форма.Объект;
			Иначе
				ОписаниеОбъекта = Объект;
			КонецЕсли;
			
			Для Каждого ЗависимыйРеквизит Из Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов Цикл
				Если ЗависимыйРеквизит.ИмяРеквизитаЗначение = Строка.ИмяРеквизитаЗначение
					И ЗависимыйРеквизит.УсловиеОбязательностиЗаполнения <> Неопределено Тогда
					
					Параметры = Новый Структура;
					Параметры.Вставить("ЗначенияПараметров", ЗависимыйРеквизит.УсловиеОбязательностиЗаполнения.ЗначенияПараметров);
					Параметры.Вставить("Форма", Форма);
					Параметры.Вставить("ОписаниеОбъекта", ОписаниеОбъекта);
					Результат = ОбщегоНазначения.ВычислитьВБезопасномРежиме(ЗависимыйРеквизит.УсловиеОбязательностиЗаполнения.КодУсловия, Параметры);
					
					Прервать;
				КонецЕсли;
			КонецЦикла;
			Если Не Результат Тогда
				Продолжить;
			КонецЕсли;
			
			Если НЕ ЗначениеЗаполнено(Форма[Строка.ИмяРеквизитаЗначение]) Тогда
				ОбщегоНазначения.СообщитьПользователю(
					СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Поле ""%1"" не заполнено.'"), Строка.Наименование),
					,
					Строка.ИмяРеквизитаЗначение,
					,
					Отказ);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

// Обновляет наборы дополнительных реквизитов и сведений для вида объектов со свойствами.
//  Используется при записи элементов справочников, которые являются видами объектов со свойствами.
//  Например, если есть справочник Номенклатура, к которому применяется подсистема Свойства, для него создан
// справочник ВидыНоменклатуры, то при записи элемента ВидНоменклатуры необходимо вызывать эту процедуру.
//
// Параметры:
//  ВидОбъекта                - СправочникОбъектИмяСправочника - например вид номенклатуры перед записью.
//  ИмяОбъектаСоСвойствами    - Строка - например "Номенклатура".
//  ИмяРеквизитаНабораСвойств - Строка - используется, когда наборов свойств несколько или
//                              используется имя реквизита основного набора, отличное от "НаборСвойств".
//
Процедура ПередЗаписьюВидаОбъекта(ВидОбъекта,
                                  ИмяОбъектаСоСвойствами,
                                  ИмяРеквизитаНабораСвойств = "НаборСвойств") Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	НаборСвойств   = ВидОбъекта[ИмяРеквизитаНабораСвойств];
	РодительНабора = НаборСвойствПоИмени(ИмяОбъектаСоСвойствами);
	Если РодительНабора = Неопределено Тогда
		РодительНабора = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяОбъектаСоСвойствами];
	КонецЕсли;
	
	Если ЗначениеЗаполнено(НаборСвойств) Тогда
		
		СтарыеСвойстваНабора = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
			НаборСвойств, "Наименование, Родитель, ПометкаУдаления");
		
		Если СтарыеСвойстваНабора.Наименование    = ВидОбъекта.Наименование
		   И СтарыеСвойстваНабора.ПометкаУдаления = ВидОбъекта.ПометкаУдаления
		   И СтарыеСвойстваНабора.Родитель        = РодительНабора Тогда
			
			Возврат;
		КонецЕсли;
		
		Если СтарыеСвойстваНабора.Родитель = РодительНабора Тогда
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
			ЭлементБлокировки.УстановитьЗначение("Ссылка", НаборСвойств);
			Блокировка.Заблокировать();
			
			ЗаблокироватьДанныеДляРедактирования(НаборСвойств);
			НаборСвойствОбъект = НаборСвойств.ПолучитьОбъект();
		Иначе
			НаборСвойствОбъект = НаборСвойств.Скопировать();
		КонецЕсли;
	Иначе
		НаборСвойствОбъект = Справочники.НаборыДополнительныхРеквизитовИСведений.СоздатьЭлемент();
		НаборСвойствОбъект.Используется = Истина;
	КонецЕсли;
	
	НаборСвойствОбъект.Наименование    = СтрЗаменить(ВидОбъекта.Наименование, ".", "");
	НаборСвойствОбъект.ПометкаУдаления = ВидОбъекта.ПометкаУдаления;
	НаборСвойствОбъект.Родитель        = РодительНабора;
	НаборСвойствОбъект.Записать();
	
	ВидОбъекта[ИмяРеквизитаНабораСвойств] = НаборСвойствОбъект.Ссылка;
	
КонецПроцедуры

// Удаляет зависимые наборы дополнительных реквизитов и сведений при удалении вида объектов со свойствами.
//
// Параметры:
//  ВидОбъекта                - СправочникОбъектИмяСправочника - например, вид номенклатуры.
//  ИмяРеквизитаНабораСвойств - Строка - используется, когда наборов свойств несколько или
//                              используется имя реквизита основного набора, отличное от "НаборСвойств".
//
Процедура ПередУдалениемВидаОбъекта(ВидОбъекта, ИмяРеквизитаНабораСвойств = "НаборСвойств") Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	НаборСвойств = ВидОбъекта[ИмяРеквизитаНабораСвойств];
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("НаборСвойств", НаборСвойств);
	Запрос.Текст =
		"ВЫБРАТЬ
		|	ДополнительныеРеквизитыИСведения.Ссылка КАК Ссылка
		|ИЗ
		|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
		|ГДЕ
		|	ДополнительныеРеквизитыИСведения.НаборСвойств = &НаборСвойств";
	Результат = Запрос.Выполнить().Выгрузить();
	ДополнительныеРеквизиты = Результат.ВыгрузитьКолонку("Ссылка");
	Для Каждого ДополнительныйРеквизит Из ДополнительныеРеквизиты Цикл
		
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", ДополнительныйРеквизит);
		Блокировка.Заблокировать();
			
		Если ОбщегоНазначения.СсылкаСуществует(ДополнительныйРеквизит) Тогда
			ДополнительныйРеквизитОбъект = ДополнительныйРеквизит.ПолучитьОбъект();
			ДополнительныйРеквизитОбъект.НаборСвойств = Справочники.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка();
			ДополнительныйРеквизитОбъект.Записать();
		КонецЕсли;
		
	КонецЦикла;
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
	ЭлементБлокировки.УстановитьЗначение("Ссылка", НаборСвойств);
	Блокировка.Заблокировать();
	
	Если ОбщегоНазначения.СсылкаСуществует(НаборСвойств) Тогда
		НаборСвойствОбъект = НаборСвойств.ПолучитьОбъект();
		НаборСвойствОбъект.Удалить(); 
	КонецЕсли;
	
КонецПроцедуры

// Обновляет отображаемые данные дополнительных реквизитов на форме объекта со свойствами.
// 
// Параметры:
//  Форма           - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
//  Объект          - Неопределено - взять объект из реквизита формы "Объект".
//                  - СправочникОбъектИмяСправочника
//                  - ДокументОбъектИмяДокумента
//                  - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                  - БизнесПроцессОбъектИмяБизнесПроцесса
//                  - ЗадачаОбъектИмяЗадачи
//                  - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                  - ПланСчетовОбъектИмяПланаСчетов
//                  - ДанныеФормыСтруктура
//
//  СкрытьУдаленные - Неопределено - не менять текущий режим скрытия удаленных, установленный ранее.
//                  - Булево - установить/отключить режим скрытия удаленных.
//                    При вызове процедуры ПередЗаписьюНаСервере в режиме скрытия удаленных удаленные значения
//                    очищаются (не переносятся обратно в объект), а режим СкрытьУдаленные устанавливается Ложь.
//
Процедура ОбновитьЭлементыДополнительныхРеквизитов(Форма, Объект = Неопределено, СкрытьУдаленные = Неопределено) Экспорт
	
	УправлениеСвойствамиСлужебный.ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект);
	ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект, , СкрытьУдаленные);
	
	УправлениеСвойствамиСлужебный.ПеренестиУстановленныеМеткиВОбъект(Форма, Объект);
	ЗаполнитьМеткиОбъекта(Форма, Объект);
	
КонецПроцедуры

// В форме списка выводит колонки с метками.
// Вызывается из события ПриПолученииДанныхНаСервере формы списка.
//
// Параметры:
//   Настройки              - НастройкиКомпоновкиДанных - содержит копию полных настроек динамического списка,
//   Строки                 - СтрокиДинамическогоСписка - коллекция содержит данные и оформление всех строк,
//   ИмяВладельца           - Строка                    - реквизит строки динамического списка, который будет
//                                                        использован для получения свойств. Если Неопределено
//                                                        используется ключи строк.
//
Процедура ПриПолученииДанныхНаСервере(Настройки, Строки, ИмяВладельца = Неопределено) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Свойства") Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ПолучитьФункциональнуюОпцию("ИспользоватьДополнительныеРеквизитыИСведения") Тогда
		Возврат;
	КонецЕсли;
	
	Ключи = Строки.ПолучитьКлючи();
	Если Ключи.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Для каждого Ключ Из Ключи Цикл
		Если ИмяВладельца <> Неопределено Тогда
			Владелец = Ключ[ИмяВладельца];
		Иначе
			Владелец = Ключ;
		КонецЕсли;
		Если ЗначениеЗаполнено(Владелец) Тогда
			ВидОбъектов = Владелец.Метаданные().ПолноеИмя();
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	СписокСвойствДляВидаОбъектов = УправлениеСвойствамиСлужебный.СписокСвойствДляВидаОбъектов(ВидОбъектов, "Метки");
	Если СписокСвойствДляВидаОбъектов = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Метки = СписокСвойствДляВидаОбъектов.ВыгрузитьКолонку("Свойство");
	РеквизитыМеток = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(Метки, "ЦветСвойств, ПометкаУдаления");
	
	Для каждого Строка Из Строки Цикл
		КлючСтроки = Строка.Ключ;
		ДанныеСтроки = Строки.Получить(КлючСтроки);
		Если ИмяВладельца <> Неопределено Тогда
			Владелец = КлючСтроки[ИмяВладельца];
		Иначе
			Владелец = КлючСтроки;
		КонецЕсли;
		Если Не ЗначениеЗаполнено(Владелец) Тогда
			Продолжить;
		КонецЕсли;
		ДополнительныеРеквизиты = Владелец.ДополнительныеРеквизиты.Выгрузить();
		Метки = СвойстваПоВидуДополнительныхРеквизитов(ДополнительныеРеквизиты, Перечисления.ВидыСвойств.Метки);
		НомерМетки = 1;
		Для каждого Метка Из Метки Цикл
			РеквизитыМетки = РеквизитыМеток.Получить(Метка);
			Если РеквизитыМетки = Неопределено Или РеквизитыМетки.ПометкаУдаления Тогда
				Продолжить;
			КонецЕсли;
			ИмяСвойства = СтрШаблон("Метка%1", НомерМетки);
			Если ДанныеСтроки.Данные.Свойство(ИмяСвойства) Тогда
				ДанныеСтроки.Данные[ИмяСвойства] =
					Перечисления.ЦветаСвойств.Индекс(РеквизитыМетки.ЦветСвойств) + 1;
				НомерМетки = НомерМетки + 1;
			Иначе
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для программной работы со свойствами

// Добавляет дополнительное свойство к переданному объекту.
//
// Параметры:
//  Владелец - ОбъектМетаданных
//           - Строка - полное имя объекта метаданных или имя набора свойств.
//           - СправочникСсылка.НаборыДополнительныхРеквизитовИСведений - ссылка на набор свойств.
//  Параметры - см. ПараметрыДобавленияСвойства.
//  ЭтоСведение - Булево - если Истина, будет добавлено дополнительное сведение.
//                         Значение по умолчанию Ложь - добавляется дополнительный реквизит.
//
Процедура ДобавитьСвойство(Владелец, Параметры, ЭтоСведение = Ложь) Экспорт
	
	Если ТипЗнч(Владелец) = Тип("ОбъектМетаданных") Тогда
		ИмяПредопределенного = СтрЗаменить(Владелец.ПолноеИмя(), ".", "_");
	ИначеЕсли ТипЗнч(Владелец) = Тип("Строка") Тогда
		Если СтрНайти(Владелец, ".") = 0 Тогда
			// Это набор свойств.
			ИмяПредопределенного = Владелец;
		Иначе
			ИмяПредопределенного = СтрЗаменить(Владелец, ".", "_");
		КонецЕсли;
	КонецЕсли;
	
	Если ТипЗнч(Владелец) = Тип("СправочникСсылка.НаборыДополнительныхРеквизитовИСведений") Тогда
		НаборСвойств = Владелец;
	Иначе
		НаборСвойств = НаборСвойствПоИмени(ИмяПредопределенного);
		Если НаборСвойств = Неопределено Тогда
			ТекстИсключения = НСтр("ru = 'Переданный объект ""%1"" не подключен к подсистеме Свойства.'");
			ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстИсключения, Владелец);
		КонецЕсли;
	КонецЕсли;
	
	ОтсутствующиеПараметры = Новый Массив;
	Если Не Параметры.Свойство("Наименование")
		Или Не ЗначениеЗаполнено(Параметры.Наименование) Тогда
		ОтсутствующиеПараметры.Добавить("Наименование");
	КонецЕсли;
	
	Если Не Параметры.Свойство("Тип") 
	 Или Не ЗначениеЗаполнено(Параметры.Тип) Тогда
		ОтсутствующиеПараметры.Добавить("Тип");
	КонецЕсли;
	
	Если ОтсутствующиеПараметры.Количество() > 0 Тогда
		ОтсутствующиеПараметры = СтрСоединить(ОтсутствующиеПараметры, ", ");
		ТекстИсключения = НСтр("ru = 'Не переданы обязательные параметры:
			|%1.'");
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстИсключения, ОтсутствующиеПараметры);
	КонецЕсли;
	
	ПустаяСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПустаяСсылка();
	// 1. Проверка, что наименование используется.
	Результат = УправлениеСвойствамиСлужебный.НаименованиеУжеИспользуется(ПустаяСсылка, НаборСвойств, Параметры.Наименование);
	Если ЗначениеЗаполнено(Результат) Тогда
		ВызватьИсключение Результат;
	КонецЕсли;
	
	// 2. Проверка, что имя уже используется.
	Если Параметры.Свойство("Имя")
		И ЗначениеЗаполнено(Параметры.Имя) Тогда
		Результат = УправлениеСвойствамиСлужебный.ИмяУжеИспользуется(Параметры.Имя, ПустаяСсылка);
		Если ЗначениеЗаполнено(Результат) Тогда
			ВызватьИсключение Результат;
		КонецЕсли;
	Иначе
		Имя = "";
		ЗаголовокОбъекта = Параметры.Наименование;
		УправлениеСвойствамиСлужебный.УдалитьНедопустимыеСимволы(ЗаголовокОбъекта);
		ЗаголовокОбъектаЧастями = СтрРазделить(ЗаголовокОбъекта, " ", Ложь);
		Для Каждого ЧастьЗаголовка Из ЗаголовокОбъектаЧастями Цикл
			Имя = Имя + ВРег(Лев(ЧастьЗаголовка, 1)) + Сред(ЧастьЗаголовка, 2);
		КонецЦикла;
		
		Если УправлениеСвойствамиСлужебный.ИмяНачинаетсяСЦифры(Имя) Тогда
			Имя = "_" + Имя;
		КонецЕсли;
		
		Результат = УправлениеСвойствамиСлужебный.ИмяУжеИспользуется(Имя, ПустаяСсылка);
		Если ЗначениеЗаполнено(Результат) Тогда
			УИД = Новый УникальныйИдентификатор();
			СтрокаУИД = СтрЗаменить(Строка(УИД), "-", "");
			Имя = Имя + "_" + СтрокаУИД;
		КонецЕсли;
		
		Параметры.Вставить("Имя", Имя);
	КонецЕсли;
	
	// 3. Проверка, что идентификатор для формул уже используется.
	Если Параметры.Свойство("ИдентификаторДляФормул")
		И ЗначениеЗаполнено(Параметры.ИдентификаторДляФормул) Тогда
		Результат = УправлениеСвойствамиСлужебный.ИдентификаторДляФормулУжеИспользуется(Параметры.ИдентификаторДляФормул, ПустаяСсылка);
		Если ЗначениеЗаполнено(Результат) Тогда
			ВызватьИсключение Результат;
		КонецЕсли;
	КонецЕсли;
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
	ЭлементБлокировки.УстановитьЗначение("Ссылка", НаборСвойств);
	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();
		
		НовоеСвойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.СоздатьЭлемент();
		ЗаполнитьЗначенияСвойств(НовоеСвойство, Параметры);
		
		НовоеСвойство.Заголовок                 = Параметры.Наименование;
		НовоеСвойство.ЭтоДополнительноеСведение = ЭтоСведение;
		НовоеСвойство.НаборСвойств              = НаборСвойств;
		
		// Для мультиязычной.
		НовоеСвойство.ЗаголовокЯзык1 = Параметры.Наименование;
		НовоеСвойство.ЗаголовокЯзык2 = Параметры.Наименование;
	
		НовоеСвойство.Записать();
		
		ОбъектНаборСвойств = НаборСвойств.ПолучитьОбъект();
		Если НовоеСвойство.ЭтоДополнительноеСведение Тогда
			ТабличнаяЧасть = ОбъектНаборСвойств.ДополнительныеСведения;
		Иначе
			ТабличнаяЧасть = ОбъектНаборСвойств.ДополнительныеРеквизиты;
		КонецЕсли;
		НайденнаяСтрока = ТабличнаяЧасть.Найти(НаборСвойств.Ссылка, "Свойство");
		Если НайденнаяСтрока = Неопределено Тогда
			НоваяСтрока = ТабличнаяЧасть.Добавить();
			НоваяСтрока.Свойство = НовоеСвойство.Ссылка;
			ОбъектНаборСвойств.Записать();
		КонецЕсли;
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

// Добавляет доступное значение для реквизита с типом ЗначенияСвойствОбъектов
// или ЗначенияСвойствОбъектовИерархия.
//
// Параметры:
//  Владелец  - Строка - имя дополнительного реквизита.
//            - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - дополнительный реквизит, 
//                для которого надо добавить значение.
//  Параметры - см. ПараметрыДобавленияЗначенияСвойства.
//  Иерархия  - Булево  
//
// Возвращаемое значение:
//  СправочникСсылка.ЗначенияСвойствОбъектов
//  СправочникСсылка.ЗначенияСвойствОбъектовИерархия
//
Функция ДобавитьЗначениеСвойства(Знач Владелец, Параметры, Иерархия = Ложь) Экспорт
	
	Если Не Параметры.Свойство("Наименование")
		Или Не ЗначениеЗаполнено(Параметры.Наименование) Тогда
		ВызватьИсключение НСтр("ru = 'Не указан обязательный параметр ""Наименование"".'");
	КонецЕсли;
	
	Если ТипЗнч(Владелец) = Тип("Строка") Тогда
		Запрос = Новый Запрос;
		Запрос.УстановитьПараметр("Имя", Владелец);
		Запрос.Текст =
			"ВЫБРАТЬ
			|	ДополнительныеРеквизитыИСведения.Ссылка КАК Ссылка
			|ИЗ
			|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
			|ГДЕ
			|	ДополнительныеРеквизитыИСведения.Имя = &Имя";
		Результат = Запрос.Выполнить().Выгрузить();
		Если Результат.Количество() = 0 Тогда
			ШаблонИсключения = НСтр("ru = 'Не найдено дополнительного реквизита с именем ""%1"".'");
			ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонИсключения, Владелец);
		КонецЕсли;
		
		Владелец = Результат[0].Ссылка;
	КонецЕсли;
	
	ТипРеквизита = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Владелец, "ТипЗначения");
	Если Не УправлениеСвойствамиСлужебный.ТипЗначенияСодержитЗначенияСвойств(ТипРеквизита) Тогда
		ШаблонИсключения = НСтр("ru = 'Добавление значений поддерживается только для дополнительных реквизитов
			|с типами ""%1"" или ""%2"". Тип значения текущего реквизита - ""%3""'");
		ШаблонИсключения = СтрЗаменить(ШаблонИсключения, Символы.ПС, " ");
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонИсключения,
			Тип("СправочникСсылка.ЗначенияСвойствОбъектов"),
			Тип("СправочникСсылка.ЗначенияСвойствОбъектовИерархия"),
			ТипРеквизита);
	КонецЕсли;
	
	ЭтоГруппа = Параметры.Свойство("ЭтоГруппа") И Параметры.ЭтоГруппа;
	Если Иерархия Тогда
		Если ЭтоГруппа Тогда
			ЗначениеРеквизита = Справочники.ЗначенияСвойствОбъектовИерархия.СоздатьГруппу();
		Иначе
			ЗначениеРеквизита = Справочники.ЗначенияСвойствОбъектовИерархия.СоздатьЭлемент();
		КонецЕсли;
	Иначе
		Если ЭтоГруппа Тогда
			ЗначениеРеквизита = Справочники.ЗначенияСвойствОбъектов.СоздатьГруппу();
		Иначе
			ЗначениеРеквизита = Справочники.ЗначенияСвойствОбъектов.СоздатьЭлемент();
		КонецЕсли;
	КонецЕсли;
	
	ЗначениеРеквизита.Владелец = Владелец;
	ЗаполнитьЗначенияСвойств(ЗначениеРеквизита, Параметры);
	
	ЗначениеРеквизита.Записать();
	
	Возврат ЗначениеРеквизита.Ссылка;
	
КонецФункции

// Возвращает параметры, необходимые для для добавления свойства.
// 
// Возвращаемое значение:
//  Структура:
//     * Наименование - Строка - обязательно для заполнения.
//     * Тип          - ОписаниеТипов - обязательно для заполнения.
//     * Имя          - Строка
//     * Комментарий  - Строка
//     * ЗаголовокФормыЗначения       - Строка
//     * ЗаголовокФормыВыбораЗначения - Строка
//     * ИдентификаторДляФормул - Строка
//     * МногострочноеПолеВвода - Булево
//     * Подсказка              - Строка
//
Функция ПараметрыДобавленияСвойства() Экспорт
	
	Параметры = Новый Структура;
	Параметры.Вставить("Наименование", "");
	Параметры.Вставить("Тип");
	Параметры.Вставить("Имя", "");
	Параметры.Вставить("Комментарий", "");
	Параметры.Вставить("ЗаголовокФормыЗначения", "");
	Параметры.Вставить("ЗаголовокФормыВыбораЗначения", "");
	Параметры.Вставить("ИдентификаторДляФормул", "");
	Параметры.Вставить("МногострочноеПолеВвода", Ложь);
	Параметры.Вставить("Подсказка", "");
	
	Возврат Параметры;
	
КонецФункции

// Возвращает параметры, требуемые для добавления значения свойства.
// 
// Возвращаемое значение:
//  Структура:
//     * Наименование - Строка - обязательно для заполнения.
//     * ПолноеНаименование - Строка
//     * Родитель - СправочникСсылка.ЗначенияСвойствОбъектов
//                - СправочникСсылка.ЗначенияСвойствОбъектовИерархия
//     * ЭтоГруппа - Булево
//
Функция ПараметрыДобавленияЗначенияСвойства() Экспорт
	
	Параметры = Новый Структура;
	Параметры.Вставить("Наименование", "");
	Параметры.Вставить("ПолноеНаименование", "");
	Параметры.Вставить("Родитель");
	Параметры.Вставить("ЭтоГруппа", Ложь);
	
	Возврат Параметры;
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Процедуры и функции для нестандартной обработки дополнительных свойств.

// Возвращает ссылку на предопределенный набор свойств по имени набора.
// Предназначена для наборов, указанных в процедуре
// УправлениеСвойствамиПереопределяемый.ПриПолученииПредопределенныхНаборовСвойств.
//
// Параметры:
//  ИмяНабора - Строка - имя получаемого набора свойств.
//
// Возвращаемое значение:
//  СправочникСсылка.НаборыДополнительныхРеквизитовИСведений - ссылка на набор свойств.
//  Неопределено - если предопределенный набор не существует.
//
// Пример:
//  Ссылка = УправлениеСвойствами.НаборСвойствПоИмени("Справочник_Пользователи");
//
Функция НаборСвойствПоИмени(ИмяНабора) Экспорт
	ПредопределенныеНаборыСвойств = УправлениеСвойствамиПовтИсп.ПредопределенныеНаборыСвойств();
	Набор = ПредопределенныеНаборыСвойств.Получить(ИмяНабора); // см. Справочники.НаборыДополнительныхРеквизитовИСведений.СвойстваНабора
	Если Набор = Неопределено Тогда
		Возврат Неопределено;
	Иначе
		Возврат Набор.Ссылка;
	КонецЕсли;
КонецФункции

// Создает/пересоздает дополнительные реквизиты и элементы в форме владельца свойств.
//
// Параметры:
//  Форма           - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
//  Объект          - Неопределено - взять объект из реквизита формы "Объект".
//                  - СправочникОбъектИмяСправочника
//                  - ДокументОбъектИмяДокумента
//                  - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                  - БизнесПроцессОбъектИмяБизнесПроцесса
//                  - ЗадачаОбъектИмяЗадачи
//                  - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                  - ПланСчетовОбъектИмяПланаСчетов
//                  - ДанныеФормыСтруктура
//
//  ПоляНадписей    - Булево - если указать Истина, то вместо полей ввода на форме будут созданы поля надписей.
//
//  СкрытьУдаленные - Неопределено - не менять текущий режим скрытия удаленных, установленный ранее.
//                  - Булево - установить/отключить режим скрытия удаленных.
//                    При вызове процедуры ПередЗаписьюНаСервере в режиме скрытия удаленных, удаленные значения
//                    очищаются (не переносятся обратно в объект), а режим СкрытьУдаленные устанавливается Ложь.
//
Процедура ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект = Неопределено, ПоляНадписей = Ложь, СкрытьУдаленные = Неопределено) Экспорт
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
	 ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(СкрытьУдаленные) = Тип("Булево") Тогда
		Форма.Свойства_СкрытьУдаленные = СкрытьУдаленные;
	КонецЕсли;
	
	Если Объект = Неопределено Тогда
		ОписаниеОбъекта = Форма.Объект;
	Иначе
		ОписаниеОбъекта = Объект;
	КонецЕсли;
	
	Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта = Новый СписокЗначений;
	
	КлючНазначения = Неопределено;
	НаборыСвойствОбъекта = УправлениеСвойствамиСлужебный.ПолучитьНаборыСвойствОбъекта(
		ОписаниеОбъекта, КлючНазначения);
	
	УправлениеСвойствамиСлужебный.ЗаполнитьНаборыСДополнительнымиРеквизитами(
		НаборыСвойствОбъекта,
		Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
	
	ОбновитьКлючНазначенияФормы(Форма, КлючНазначения);
	
	ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеРеквизиты;
	ОписаниеСвойств = УправлениеСвойствамиСлужебный.ЗначенияСвойств(
		ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить(),
		Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта,
		ВидСвойств);
	
	ОписаниеСвойств.Колонки.Добавить("ИмяРеквизитаЗначение");
	ОписаниеСвойств.Колонки.Добавить("СтрокаСсылочногоТипа");
	ОписаниеСвойств.Колонки.Добавить("ИмяСсылочногоРеквизитаЗначение");
	ОписаниеСвойств.Колонки.Добавить("ИмяУникальнаяЧасть");
	ОписаниеСвойств.Колонки.Добавить("ДополнительноеЗначение");
	ОписаниеСвойств.Колонки.Добавить("Булево");
	
	УдалитьСтарыеРеквизитыИЭлементы(Форма);
	
	// Создание реквизитов.
	ДобавляемыеРеквизиты = Новый Массив();
	
	Для каждого ОписаниеСвойства Из ОписаниеСвойств Цикл
		
		ТипЗначенияСвойства = ОписаниеСвойства.ТипЗначения;
		СписокТипов = ТипЗначенияСвойства.Типы();
		СтроковыйРеквизит = (СписокТипов.Количество() = 1) И (СписокТипов[0] = Тип("Строка"));
		
		// Поддержка строк неограниченной длины.
		ИспользоватьНеограниченнуюСтроку = УправлениеСвойствамиСлужебный.ИспользоватьНеограниченнуюСтроку(
			ТипЗначенияСвойства, ОписаниеСвойства.МногострочноеПолеВвода);
		
		Если ИспользоватьНеограниченнуюСтроку Тогда
			ТипЗначенияСвойства = Новый ОписаниеТипов("Строка");
		ИначеЕсли ТипЗначенияСвойства.СодержитТип(Тип("Строка"))
			И ТипЗначенияСвойства.КвалификаторыСтроки.Длина = 0 Тогда
			// Если нельзя использовать неограниченную строку, а в свойствах реквизита она неограниченная,
			// то устанавливаем ограничение в 1024 символа.
			ТипЗначенияСвойства = Новый ОписаниеТипов(ОписаниеСвойства.ТипЗначения,
				,,, Новый КвалификаторыСтроки(1024));
		КонецЕсли;
		
		ОписаниеСвойства.ИмяУникальнаяЧасть = 
			СтрЗаменить(ВРег(Строка(ОписаниеСвойства.Набор.УникальныйИдентификатор())), "-", "x")
			+ "_"
			+ СтрЗаменить(ВРег(Строка(ОписаниеСвойства.Свойство.УникальныйИдентификатор())), "-", "x");
		
		ОписаниеСвойства.ИмяРеквизитаЗначение =
			"ДополнительныйРеквизитЗначение_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
		
		ОписаниеСвойства.СтрокаСсылочногоТипа = Ложь;
		Если СтроковыйРеквизит
			И Не ИспользоватьНеограниченнуюСтроку
			И ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
			ФорматированнаяСтрока                           = Новый ОписаниеТипов("ФорматированнаяСтрока");
			ОписаниеСвойства.СтрокаСсылочногоТипа           = Истина;
			ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение = "СсылочныйДополнительныйРеквизитЗначение_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
			
			Реквизит = Новый РеквизитФормы(ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение, ФорматированнаяСтрока, , ОписаниеСвойства.Наименование, Истина);
			ДобавляемыеРеквизиты.Добавить(Реквизит);
		КонецЕсли;
		
		Если ОписаниеСвойства.Удалено Тогда
			ТипЗначенияСвойства = Новый ОписаниеТипов("Строка");
		КонецЕсли;
		
		Реквизит = Новый РеквизитФормы(ОписаниеСвойства.ИмяРеквизитаЗначение, ТипЗначенияСвойства, , ОписаниеСвойства.Наименование, Истина);
		ДобавляемыеРеквизиты.Добавить(Реквизит);
		
		ОписаниеСвойства.ДополнительноеЗначение =
			УправлениеСвойствамиСлужебный.ТипЗначенияСодержитЗначенияСвойств(ТипЗначенияСвойства);
		
		ОписаниеСвойства.Булево = ОбщегоНазначения.ОписаниеТипаСостоитИзТипа(ТипЗначенияСвойства, Тип("Булево"));
	КонецЦикла;
	Форма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
	
	// Создание элементов формы.
	Для Каждого ОписаниеСвойства Из ОписаниеСвойств Цикл
		
		ИмяЭлементаДляРазмещения = Форма.Свойства_ИмяЭлементаДляРазмещения;
		Если ТипЗнч(ИмяЭлементаДляРазмещения) <> Тип("СписокЗначений") Тогда
			Если ИмяЭлементаДляРазмещения = Неопределено Тогда
				ИмяЭлементаДляРазмещения = "";
			КонецЕсли;
			
			ЭлементРазмещения = ?(ИмяЭлементаДляРазмещения = "", Неопределено, Форма.Элементы[ИмяЭлементаДляРазмещения]);
		Иначе
			РазделыДляРазмещения = Форма.Свойства_ИмяЭлементаДляРазмещения;
			РазмещениеНабора = РазделыДляРазмещения.НайтиПоЗначению(ОписаниеСвойства.Набор);
			Если РазмещениеНабора = Неопределено Тогда
				РазмещениеНабора = РазделыДляРазмещения.НайтиПоЗначению("ВсеОстальные");
			КонецЕсли;
			ЭлементРазмещения = Форма.Элементы[РазмещениеНабора.Представление];
		КонецЕсли;
		
		ФормаОписаниеСвойства = Форма.Свойства_ОписаниеДополнительныхРеквизитов.Добавить();
		ЗаполнитьЗначенияСвойств(ФормаОписаниеСвойства, ОписаниеСвойства);
		
		// Заполнение таблицы зависимых дополнительных реквизитов.
		Если ОписаниеСвойства.ЗависимостиДополнительныхРеквизитов.Количество() > 0
			И Не ОписаниеСвойства.Удалено Тогда
			ОписаниеЗависимогоРеквизита = Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов.Добавить();
			ЗаполнитьЗначенияСвойств(ОписаниеЗависимогоРеквизита, ОписаниеСвойства);
		КонецЕсли;
		
		ОтборСтрок = Новый Структура;
		ОтборСтрок.Вставить("НаборСвойств", ОписаниеСвойства.Набор);
		ЗависимостиДанногоНабора = ОписаниеСвойства.ЗависимостиДополнительныхРеквизитов.НайтиСтроки(ОтборСтрок);
		Для Каждого СтрокаТаблицы Из ЗависимостиДанногоНабора Цикл
			Если СтрокаТаблицы.ЗависимоеСвойство = "ЗаполнятьОбязательно"
				И ОписаниеСвойства.ТипЗначения = Новый ОписаниеТипов("Булево") Тогда
				Продолжить;
			КонецЕсли;
			Если ОписаниеСвойства.Удалено Тогда
				Продолжить;
			КонецЕсли;
			
			Если ТипЗнч(СтрокаТаблицы.Реквизит) = Тип("Строка") Тогда
				ПутьКРеквизиту = "Параметры.ОписаниеОбъекта." + СтрокаТаблицы.Реквизит;
			Иначе
				ОписаниеДополнительногоРеквизита = ОписаниеСвойств.Найти(СтрокаТаблицы.Реквизит, "Свойство");
				Если ОписаниеДополнительногоРеквизита = Неопределено Тогда
					Продолжить; // Дополнительный реквизит не существует, условие игнорируется.
				КонецЕсли;
				ПутьКРеквизиту = "Параметры.Форма." + ОписаниеДополнительногоРеквизита.ИмяРеквизитаЗначение;
			КонецЕсли;
			
			УправлениеСвойствамиСлужебный.ПостроитьУсловияЗависимостей(ОписаниеЗависимогоРеквизита, ПутьКРеквизиту, СтрокаТаблицы);
		КонецЦикла;
		
		Если ОписаниеСвойства.СтрокаСсылочногоТипа Тогда
			Если ЗначениеЗаполнено(ОписаниеСвойства.Значение) Тогда
				Значение = ОписаниеСвойства.ТипЗначения.ПривестиЗначение(ОписаниеСвойства.Значение);
				СтрокаЗначение = СтроковыеФункции.ФорматированнаяСтрока(Значение);
			Иначе
				Значение = НСтр("ru = 'не задано'");
				СсылкаРедактирования = "НеЗадано";
				СтрокаЗначение = Новый ФорматированнаяСтрока(Значение,, ЦветаСтиля.ЦветПустойГиперссылки,, СсылкаРедактирования);
			КонецЕсли;
			Форма[ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение] = СтрокаЗначение;
		КонецЕсли;
		Форма[ОписаниеСвойства.ИмяРеквизитаЗначение] = ОписаниеСвойства.Значение;
		
		Если ОписаниеСвойства.Удалено И Форма.Свойства_СкрытьУдаленные Тогда
			Продолжить;
		КонецЕсли;
		
		Если НаборыСвойствОбъекта.Количество() > 1 Тогда
			
			ЭлементСписка = Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов.НайтиПоЗначению(
				ОписаниеСвойства.Набор);
			
			Если ЭлементСписка <> Неопределено Тогда
				Родитель = Форма.Элементы[ЭлементСписка.Представление];
			Иначе
				ОписаниеНабора = НаборыСвойствОбъекта.Найти(ОписаниеСвойства.Набор, "Набор");
				
				Если ОписаниеНабора = Неопределено Тогда
					ОписаниеНабора = НаборыСвойствОбъекта.Добавить();
					ОписаниеНабора.Набор     = ОписаниеСвойства.Набор;
					ОписаниеНабора.Заголовок = НСтр("ru = 'Удаленные реквизиты'")
				КонецЕсли;
				
				Если НЕ ЗначениеЗаполнено(ОписаниеНабора.Заголовок) Тогда
					ОписаниеНабора.Заголовок = Строка(ОписаниеСвойства.Набор);
				КонецЕсли;
				
				ИмяЭлементаНабора = "НаборДополнительныхРеквизитов" + ОписаниеСвойства.ИмяУникальнаяЧасть;
				
				Родитель = Форма.Элементы.Добавить(ИмяЭлементаНабора, Тип("ГруппаФормы"), ЭлементРазмещения);
				
				Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов.Добавить(
					ОписаниеСвойства.Набор, Родитель.Имя);
				
				Если ТипЗнч(ЭлементРазмещения) = Тип("ГруппаФормы")
				   И ЭлементРазмещения.Вид = ВидГруппыФормы.Страницы Тогда
					
					Родитель.Вид = ВидГруппыФормы.Страница;
				Иначе
					Родитель.Вид = ВидГруппыФормы.ОбычнаяГруппа;
					Родитель.Отображение = ОтображениеОбычнойГруппы.Нет;
				КонецЕсли;
				Родитель.ОтображатьЗаголовок = Ложь;
				Родитель.Группировка = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
				
				ЗаполненныеСвойстваГруппы = Новый Структура;
				Для каждого Колонка Из НаборыСвойствОбъекта.Колонки Цикл
					Если ОписаниеНабора[Колонка.Имя] <> Неопределено Тогда
						ЗаполненныеСвойстваГруппы.Вставить(Колонка.Имя, ОписаниеНабора[Колонка.Имя]);
					КонецЕсли;
				КонецЦикла;
				ЗаполнитьЗначенияСвойств(Родитель, ЗаполненныеСвойстваГруппы);
			КонецЕсли;
		Иначе
			Родитель = ЭлементРазмещения;
		КонецЕсли;
		
		Если ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
			ИмяГруппыГиперссылки = "Группа_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
			ГруппаГиперссылки = Форма.Элементы.Добавить(ИмяГруппыГиперссылки, Тип("ГруппаФормы"), Родитель);
			ГруппаГиперссылки.Вид = ВидГруппыФормы.ОбычнаяГруппа;
			ГруппаГиперссылки.Отображение = ОтображениеОбычнойГруппы.Нет;
			ГруппаГиперссылки.ОтображатьЗаголовок = Ложь;
			ГруппаГиперссылки.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
			ГруппаГиперссылки.Заголовок = ОписаниеСвойства.Наименование;
			
			Элемент = Форма.Элементы.Добавить(ОписаниеСвойства.ИмяРеквизитаЗначение, Тип("ПолеФормы"), ГруппаГиперссылки); // РасширениеПоляФормыДляПоляНадписи, РасширениеПоляФормыДляПоляВвода
			
			РеквизитДоступен = РеквизитДоступенПоФункциональнымОпциям(ОписаниеСвойства);
			Если РеквизитДоступен И Не ПоляНадписей Тогда
				ИмяКнопки = "Кнопка_" + ОписаниеСвойства.ИмяУникальнаяЧасть;
				Кнопка = Форма.Элементы.Добавить(
					ИмяКнопки,
					Тип("КнопкаФормы"),
					ГруппаГиперссылки);
				
				ЗаголовокКнопки = НСтр("ru = 'Начать/закончить редактирование реквизита %1'");
				Кнопка.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ЗаголовокКнопки, ОписаниеСвойства.Наименование);
				Кнопка.ПоложениеВКоманднойПанели = ПоложениеКнопкиВКоманднойПанели.ВДополнительномПодменю;
				Кнопка.ИмяКоманды = "РедактироватьГиперссылкуРеквизита";
				Кнопка.ОтображениеФигуры = ОтображениеФигурыКнопки.ПриАктивности;
			КонецЕсли;
			
			Если Не ОписаниеСвойства.СтрокаСсылочногоТипа И ЗначениеЗаполнено(ОписаниеСвойства.Значение) Тогда
				Элемент.Гиперссылка = Истина;
			КонецЕсли;
		Иначе
			Элемент = Форма.Элементы.Добавить(ОписаниеСвойства.ИмяРеквизитаЗначение, Тип("ПолеФормы"), Родитель); // РасширениеПоляФормыДляПоляНадписи, РасширениеПоляФормыДляПоляВвода
		КонецЕсли;
		
		ФормаОписаниеСвойства.ЭлементФормыДобавлен = Истина;
		
		Если ОписаниеСвойства.Булево И ПустаяСтрока(ОписаниеСвойства.ФорматСвойства) Тогда
			Элемент.Вид = ВидПоляФормы.ПолеФлажка;
			Элемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Право;
		Иначе
			Если ПоляНадписей Тогда
				Элемент.Вид = ВидПоляФормы.ПолеВвода;
			ИначеЕсли ОписаниеСвойства.ВыводитьВВидеГиперссылки
				И (ОписаниеСвойства.СтрокаСсылочногоТипа
					Или ЗначениеЗаполнено(ОписаниеСвойства.Значение))Тогда
				Элемент.Вид = ВидПоляФормы.ПолеНадписи;
			Иначе
				Элемент.Вид = ВидПоляФормы.ПолеВвода;
				Элемент.АвтоОтметкаНезаполненного = ОписаниеСвойства.ЗаполнятьОбязательно И НЕ ОписаниеСвойства.Удалено;
			КонецЕсли;
			
			Элемент.РастягиватьПоВертикали = Ложь;
			Элемент.ПоложениеЗаголовка     = ПоложениеЗаголовкаЭлементаФормы.Лево;
		КонецЕсли;
		
		Если ОписаниеСвойства.СтрокаСсылочногоТипа Тогда
			Элемент.ПутьКДанным = ОписаниеСвойства.ИмяСсылочногоРеквизитаЗначение;
			Элемент.УстановитьДействие("ОбработкаНавигационнойСсылки", "Подключаемый_СвойстваВыполнитьКоманду");
		Иначе
			Элемент.ПутьКДанным = ОписаниеСвойства.ИмяРеквизитаЗначение;
		КонецЕсли;
		Элемент.Подсказка   = ОписаниеСвойства.Подсказка;
		Элемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПриИзмененииДополнительногоРеквизита");
		
		Если Элемент.Вид = ВидПоляФормы.ПолеВвода
		   И Не ИспользоватьНеограниченнуюСтроку
		   И ОписаниеСвойства.ТипЗначения.Типы().Найти(Тип("Строка")) <> Неопределено Тогда
			
			Элемент.СвязьПоТипу = Новый СвязьПоТипу("Свойства_ОписаниеДополнительныхРеквизитов.Свойство",
				ОписаниеСвойств.Индекс(ОписаниеСвойства));
		КонецЕсли;
		
		Если ОписаниеСвойства.МногострочноеПолеВвода > 0 Тогда
			Если НЕ ПоляНадписей Тогда
				Элемент.МногострочныйРежим = Истина;
			КонецЕсли;
			Элемент.Высота = ОписаниеСвойства.МногострочноеПолеВвода;
		КонецЕсли;
		
		Если НЕ ПустаяСтрока(ОписаниеСвойства.ФорматСвойства)
			И Не ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
			Если ПоляНадписей Тогда
				Элемент.Формат = ОписаниеСвойства.ФорматСвойства;
			Иначе
				ФорматнаяСтрока = "";
				Массив = СтрРазделить(ОписаниеСвойства.ФорматСвойства, ";", Ложь);
				
				Для каждого Подстрока Из Массив Цикл
					Если СтрНайти(Подстрока, "ДП=") > 0 ИЛИ СтрНайти(Подстрока, "DE=") > 0 Тогда // @Non-NLS
						Продолжить;
					КонецЕсли;
					Если СтрНайти(Подстрока, "ЧН=") > 0 ИЛИ СтрНайти(Подстрока, "NZ=") > 0 Тогда // @Non-NLS
						Продолжить;
					КонецЕсли;
					Если СтрНайти(Подстрока, "ДФ=") > 0 ИЛИ СтрНайти(Подстрока, "DF=") > 0 Тогда // @Non-NLS
						Если СтрНайти(Подстрока, "ддд") > 0 ИЛИ СтрНайти(Подстрока, "ddd") > 0 Тогда // @Non-NLS
							Подстрока = СтрЗаменить(Подстрока, "ддд", "дд"); // @Non-NLS-1, @Non-NLS-2
							Подстрока = СтрЗаменить(Подстрока, "ddd", "dd");
						КонецЕсли;
						Если СтрНайти(Подстрока, "дддд") > 0 ИЛИ СтрНайти(Подстрока, "dddd") > 0 Тогда // @Non-NLS
							Подстрока = СтрЗаменить(Подстрока, "дддд", "дд"); // @Non-NLS-1, @Non-NLS-2
							Подстрока = СтрЗаменить(Подстрока, "dddd", "dd");
						КонецЕсли;
						Если СтрНайти(Подстрока, "МММ") > 0 ИЛИ СтрНайти(Подстрока, "MMM") > 0 Тогда // @Non-NLS
							Подстрока = СтрЗаменить(Подстрока, "МММ", "ММ"); // @Non-NLS-1, @Non-NLS-2
							Подстрока = СтрЗаменить(Подстрока, "MMM", "MM");
						КонецЕсли;
						Если СтрНайти(Подстрока, "ММММ") > 0 ИЛИ СтрНайти(Подстрока, "MMMM") > 0 Тогда // @Non-NLS
							Подстрока = СтрЗаменить(Подстрока, "ММММ", "ММ"); // @Non-NLS-1, @Non-NLS-2
							Подстрока = СтрЗаменить(Подстрока, "MMMM", "MM");
						КонецЕсли;
					КонецЕсли;
					Если СтрНайти(Подстрока, "ДЛФ=") > 0 ИЛИ СтрНайти(Подстрока, "DLF=") > 0 Тогда // @Non-NLS
						Если СтрНайти(Подстрока, "ДД") > 0 ИЛИ СтрНайти(Подстрока, "DD") > 0 Тогда // @Non-NLS
							Подстрока = СтрЗаменить(Подстрока, "ДД", "Д"); // @Non-NLS-1, @Non-NLS-2
							Подстрока = СтрЗаменить(Подстрока, "DD", "D");
						КонецЕсли;
					КонецЕсли;
					ФорматнаяСтрока = ФорматнаяСтрока + ?(ФорматнаяСтрока = "", "", ";") + Подстрока;
				КонецЦикла;
				
				Элемент.Формат = ФорматнаяСтрока;
				Элемент.ФорматРедактирования = ФорматнаяСтрока;
			КонецЕсли;
		КонецЕсли;
		
		Если ОписаниеСвойства.Удалено Тогда
			Элемент.ЦветТекстаЗаголовка = ЦветаСтиля.ТекстЗапрещеннойЯчейкиЦвет;
			Элемент.ШрифтЗаголовка = ШрифтыСтиля.ЗаголовокУдаленногоРеквизитаШрифт;
			Если Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
				Элемент.КнопкаОчистки = Истина;
				Элемент.КнопкаВыбора = Ложь;
				Элемент.КнопкаОткрытия = Ложь;
				Элемент.КнопкаВыпадающегоСписка = Ложь;
				Элемент.РедактированиеТекста = Ложь;
			КонецЕсли;
		КонецЕсли;
		
		ЭтоЗначенияСвойств = ОписаниеСвойства.ТипЗначения.Типы().Количество() = 1
			И ОписаниеСвойства.ТипЗначения.СодержитТип(Тип("СправочникСсылка.ЗначенияСвойствОбъектов"));
		
		Если НЕ ПоляНадписей И Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
			Если ЭтоЗначенияСвойств Тогда
				Элемент.ВыборГруппИЭлементов = ГруппыИЭлементы.Элементы;
			Иначе
				Элемент.ВыборГруппИЭлементов = ГруппыИЭлементы.ГруппыИЭлементы;
			КонецЕсли;
		КонецЕсли;
		
		Если НЕ ПоляНадписей И ОписаниеСвойства.ДополнительноеЗначение И Элемент.Вид = ВидПоляФормы.ПолеВвода Тогда
			ПараметрыВыбора = Новый Массив;
			ПараметрыВыбора.Добавить(Новый ПараметрВыбора("Отбор.Владелец",
				?(ЗначениеЗаполнено(ОписаниеСвойства.ВладелецДополнительныхЗначений),
					ОписаниеСвойства.ВладелецДополнительныхЗначений, ОписаниеСвойства.Свойство)));
			Элемент.ПараметрыВыбора = Новый ФиксированныйМассив(ПараметрыВыбора);
		КонецЕсли;
		
	КонецЦикла;
	
	// Установка видимости, доступности и обязательности заполнения дополнительных реквизитов.
	Для Каждого ОписаниеЗависимогоРеквизита Из Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов Цикл
		Если ОписаниеЗависимогоРеквизита.ВыводитьВВидеГиперссылки Тогда
			ОбрабатываемыйЭлемент = СтрЗаменить(ОписаниеЗависимогоРеквизита.ИмяРеквизитаЗначение, "ДополнительныйРеквизитЗначение_", "Группа_");
		Иначе
			ОбрабатываемыйЭлемент = ОписаниеЗависимогоРеквизита.ИмяРеквизитаЗначение;
		КонецЕсли;
		
		Если ОписаниеЗависимогоРеквизита.УсловиеДоступности <> Неопределено Тогда
			Результат = РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, ОписаниеЗависимогоРеквизита.УсловиеДоступности);
			Элемент = Форма.Элементы[ОбрабатываемыйЭлемент]; // ПолеФормы
			Если Элемент.Доступность <> Результат Тогда
				Элемент.Доступность = Результат;
			КонецЕсли;
		КонецЕсли;
		Если ОписаниеЗависимогоРеквизита.УсловиеВидимости <> Неопределено Тогда
			Результат = РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, ОписаниеЗависимогоРеквизита.УсловиеВидимости);
			Элемент = Форма.Элементы[ОбрабатываемыйЭлемент];
			Если Элемент.Видимость <> Результат Тогда
				Элемент.Видимость = Результат;
			КонецЕсли;
		КонецЕсли;
		Если ОписаниеЗависимогоРеквизита.УсловиеОбязательностиЗаполнения <> Неопределено Тогда
			Если Не ОписаниеЗависимогоРеквизита.ЗаполнятьОбязательно Тогда
				Продолжить;
			КонецЕсли;
			
			Результат = РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, ОписаниеЗависимогоРеквизита.УсловиеОбязательностиЗаполнения);
			Элемент = Форма.Элементы[ОбрабатываемыйЭлемент];
			Если Не ОписаниеЗависимогоРеквизита.ВыводитьВВидеГиперссылки
				И Элемент.АвтоОтметкаНезаполненного <> Результат Тогда
				Элемент.АвтоОтметкаНезаполненного = Результат;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Структура = Новый Структура("ПараметрыСвойств");
	ЗаполнитьЗначенияСвойств(Структура, Форма);
	Если ТипЗнч(Структура.ПараметрыСвойств) = Тип("Структура")
		И Структура.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация") Тогда
		Форма.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация = Истина;
		// Удаление временной декорации, если она была добавлена.
		Если Форма.ПараметрыСвойств.Свойство("ДобавленаПустаяДекорация") Тогда
			Для Каждого ИмяДекорации Из Форма.ПараметрыСвойств.КоллекцияДекораций Цикл
				Форма.Элементы.Удалить(Форма.Элементы[ИмяДекорации]);
			КонецЦикла;
			Форма.ПараметрыСвойств.Удалить("ДобавленаПустаяДекорация");
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

// Переносит значения свойств из реквизитов формы в табличную часть объекта.
// 
// Параметры:
//  Форма        - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//  Объект       - Неопределено - взять объект из реквизита формы "Объект".
//               - СправочникОбъект, ДокументОбъект, ДанныеФормыСтруктура - объект со свойствами или
//                 реквизит формы, содержащий объект.
//
Процедура ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект = Неопределено) Экспорт
	
	УправлениеСвойствамиСлужебный.ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект);
	
КонецПроцедуры

// Удаляет старые реквизиты и элементы формы.
// 
// Параметры:
//  Форма        - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//  
Процедура УдалитьСтарыеРеквизитыИЭлементы(Форма) Экспорт
	
	УдаляемыеРеквизиты = Новый Массив;
	Для каждого ОписаниеСвойства Из Форма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		УникальнаяЧасть = СтрЗаменить(ОписаниеСвойства.ИмяРеквизитаЗначение, "ДополнительныйРеквизитЗначение_", "");
		
		УдаляемыеРеквизиты.Добавить(ОписаниеСвойства.ИмяРеквизитаЗначение);
		Если ОписаниеСвойства.СтрокаСсылочногоТипа Тогда
			УдаляемыеРеквизиты.Добавить("СсылочныйДополнительныйРеквизитЗначение_" + УникальнаяЧасть);
		КонецЕсли;
		Если ОписаниеСвойства.ЭлементФормыДобавлен Тогда
			Если ОписаниеСвойства.ВыводитьВВидеГиперссылки Тогда
				Форма.Элементы.Удалить(Форма.Элементы["Группа_" + УникальнаяЧасть]);
			Иначе
				Форма.Элементы.Удалить(Форма.Элементы[ОписаниеСвойства.ИмяРеквизитаЗначение]);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если УдаляемыеРеквизиты.Количество() > 0 Тогда
		Форма.ИзменитьРеквизиты(, УдаляемыеРеквизиты);
	КонецЕсли;
	
	Для каждого ЭлементСписка Из Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов Цикл
		Форма.Элементы.Удалить(Форма.Элементы[ЭлементСписка.Представление]);
	КонецЦикла;
	
	Форма.Свойства_ОписаниеДополнительныхРеквизитов.Очистить();
	Форма.Свойства_ЭлементыГруппДополнительныхРеквизитов.Очистить();
	Форма.Свойства_ОписаниеЗависимыхДополнительныхРеквизитов.Очистить();
	
КонецПроцедуры

// Возвращает свойства у указанного объекта.
//
// Параметры:
//  ВладелецСвойств      - ЛюбаяСсылка - например: СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//                       - СправочникОбъект, ДокументОбъект - любой объект со свойствами.
//                       - ДанныеФормыСтруктура - коллекция по типу объекта владельца свойств.
//  ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты.
//  ПолучатьДопСведения  - Булево - в результат включать дополнительные сведения.
//
// Возвращаемое значение:
//  Массив из ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
//
Функция СвойстваОбъекта(ВладелецСвойств,
					    ПолучатьДопРеквизиты = Истина,
					    ПолучатьДопСведения = Истина) Экспорт
	
	Если НЕ (ПолучатьДопРеквизиты ИЛИ ПолучатьДопСведения) Тогда
		Возврат Новый Массив;
	КонецЕсли;
	
	ПолучатьДопСведения = ПолучатьДопСведения И ПравоДоступа("Чтение", Метаданные.РегистрыСведений.ДополнительныеСведения);
	
	УстановитьПривилегированныйРежим(Истина);
	НаборыСвойствОбъекта = УправлениеСвойствамиСлужебный.ПолучитьНаборыСвойствОбъекта(
		ВладелецСвойств);
	УстановитьПривилегированныйРежим(Ложь);
	
	МассивНаборовСвойствОбъекта = НаборыСвойствОбъекта.ВыгрузитьКолонку("Набор");
	
	ТекстЗапросаДопРеквизиты = 
		"ВЫБРАТЬ
		|	ТаблицаСвойств.Свойство КАК Свойство
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК ТаблицаСвойств
		|ГДЕ
		|	ТаблицаСвойств.Ссылка В (&МассивНаборовСвойствОбъекта)";
	
	ТекстЗапросаДопСведения = 
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ТаблицаСвойств.Свойство КАК Свойство
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения КАК ТаблицаСвойств
		|ГДЕ
		|	ТаблицаСвойств.Ссылка В (&МассивНаборовСвойствОбъекта)";
	
	Запрос = Новый Запрос;
	ТекстЗапроса = "";
	Если ПолучатьДопСведения Тогда
		ТекстЗапроса = ТекстЗапросаДопСведения;
	КонецЕсли;
	
	Если ПолучатьДопРеквизиты Тогда
		Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
			ТекстЗапроса = ТекстЗапроса + "
			|
			| ОБЪЕДИНИТЬ ВСЕ
			|" + ТекстЗапросаДопРеквизиты;
		Иначе
			ТекстЗапроса = ТекстЗапросаДопРеквизиты;
		КонецЕсли;
	КонецЕсли;
	
	Запрос.Текст = ТекстЗапроса;
	Запрос.Параметры.Вставить("МассивНаборовСвойствОбъекта", МассивНаборовСвойствОбъекта);
	
	Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Свойство");
	
	Возврат Результат;
	
КонецФункции

// АПК:142-выкл Проектное решение

// Возвращает значения дополнительных свойств объектов.
//
// Параметры:
//  ОбъектыСоСвойствами  - Массив      - объекты, для которых нужно получить значения дополнительных свойств.
//                                       Допустимо передавать объекты только одного типа.
//                       - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
//                                       ДокументСсылка.ЗаказПокупателя, ...
//  ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты. По умолчанию Истина.
//  ПолучатьДопСведения  - Булево - в результат включать дополнительные сведения. По умолчанию Истина.
//  Свойства             - Массив из ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - значения
//                            которых следует получить.
//                       - Массив из Строка - уникальное имя дополнительного свойства. 
//                       - Неопределено - по умолчанию, получить значения всех свойств владельца.
//  КодЯзыка             - Строка - код языка, на котором будет получено представление значения свойства.
//                                  Если не указано - берется текущий язык.
//
// Возвращаемое значение:
//  ТаблицаЗначений:
//    * Свойство    - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство владельца.
//    * ИмяСвойства - Строка - уникальное имя свойства владельца.
//    * Значение    - Произвольный - значения любого типа из описания типов свойства объекта метаданных:
//                    "Метаданные.ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Тип".
//    * Представление   - Строка - представление значения на указанном языке.
//    * ВладелецСвойств - ЛюбаяСсылка - ссылка на объект.
//
Функция ЗначенияСвойств(ОбъектыСоСвойствами,
                        ПолучатьДопРеквизиты = Истина,
                        ПолучатьДопСведения = Истина,
                        Свойства = Неопределено,
                        КодЯзыка = "") Экспорт
	
	Если Не СвойстваДоступны() Тогда
		Возврат Новый ТаблицаЗначений;
	КонецЕсли;
	
	ПолучатьДопСведения = ПолучатьДопСведения И ПравоДоступа("Чтение", Метаданные.РегистрыСведений.ДополнительныеСведения);
	
	Если ТипЗнч(ОбъектыСоСвойствами) = Тип("Массив") Тогда
		ВладелецСвойств = ОбъектыСоСвойствами[0];
	Иначе
		ВладелецСвойств = ОбъектыСоСвойствами;
	КонецЕсли;
	
	ИмяОбъектаСоСвойствами = ОбщегоНазначения.ИмяТаблицыПоСсылке(ВладелецСвойств);
	ВсеРеквизиты = Новый Массив;
	Если ПолучатьДопРеквизиты Тогда
		ПолучатьДопРеквизиты = ИспользоватьДопРеквизиты(ВладелецСвойств);
		Если ПолучатьДопРеквизиты И Свойства = Неопределено Тогда
			РеквизитыОбъекта = УправлениеСвойствамиСлужебный.СписокСвойствДляВидаОбъектов(ИмяОбъектаСоСвойствами, "ДополнительныеРеквизиты");
			Если РеквизитыОбъекта <> Неопределено Тогда
				ВсеРеквизиты = РеквизитыОбъекта.ВыгрузитьКолонку("Свойство");
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	ВсеСведения = Новый Массив;
	Если ПолучатьДопСведения Тогда
		ПолучатьДопСведения = ИспользоватьДопСведения(ВладелецСвойств);
		Если ПолучатьДопСведения И Свойства = Неопределено Тогда
			СведенияОбъекта = УправлениеСвойствамиСлужебный.СписокСвойствДляВидаОбъектов(ИмяОбъектаСоСвойствами, "ДополнительныеСведения");
			Если СведенияОбъекта <> Неопределено Тогда
				ВсеСведения = СведенияОбъекта.ВыгрузитьКолонку("Свойство");
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если Не ПолучатьДопРеквизиты И Не ПолучатьДопСведения Тогда
		Возврат Новый ТаблицаЗначений;
	КонецЕсли;
	
	Если Свойства = Неопределено Тогда
		Свойства = ВсеРеквизиты;
		ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Свойства, ВсеСведения);
	КонецЕсли;
	
	ТекстЗапросаДопРеквизиты =
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ТаблицаСвойств.Свойство КАК Свойство,
		|	ТаблицаСвойств.Значение КАК Значение,
		|	ТаблицаСвойств.ТекстоваяСтрока,
		|	ТаблицаСвойств.Ссылка КАК ВладелецСвойств,
		|	ДополнительныеРеквизитыИСведения.Имя КАК ИмяСвойства
		|ИЗ
		|	&ИмяОбъектаСДополнительнымиРеквизитами КАК ТаблицаСвойств
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
		|		ПО ДополнительныеРеквизитыИСведения.Ссылка = ТаблицаСвойств.Свойство
		|ГДЕ
		|	ТаблицаСвойств.Ссылка В (&ОбъектыСоСвойствами)
		|	И (ДополнительныеРеквизитыИСведения.Ссылка В (&Свойства)
		|		ИЛИ ДополнительныеРеквизитыИСведения.Имя В (&Свойства))";
	
	ТекстЗапросаДопСведения =
		"ВЫБРАТЬ РАЗРЕШЕННЫЕ
		|	ТаблицаСвойств.Свойство КАК Свойство,
		|	ТаблицаСвойств.Значение КАК Значение,
		|	"""" КАК ТекстоваяСтрока,
		|	ТаблицаСвойств.Объект КАК ВладелецСвойств,
		|	ДополнительныеРеквизитыИСведения.Имя КАК ИмяСвойства
		|ИЗ
		|	РегистрСведений.ДополнительныеСведения КАК ТаблицаСвойств
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
		|		ПО ДополнительныеРеквизитыИСведения.Ссылка = ТаблицаСвойств.Свойство
		|ГДЕ
		|	ТаблицаСвойств.Объект В (&ОбъектыСоСвойствами)
		|	И (ДополнительныеРеквизитыИСведения.Ссылка В (&Свойства)
		|		ИЛИ ДополнительныеРеквизитыИСведения.Имя В (&Свойства))";
	
	Запрос = Новый Запрос;
	ТекстЗапроса = "";
	Если ПолучатьДопРеквизиты Тогда
		ТекстЗапроса = ТекстЗапросаДопРеквизиты;
	КонецЕсли;
	
	Если ПолучатьДопСведения Тогда
		Если ЗначениеЗаполнено(ТекстЗапроса) Тогда
			ТекстЗапроса = ТекстЗапроса + "
			|
			| ОБЪЕДИНИТЬ ВСЕ
			|" + СтрЗаменить(ТекстЗапросаДопСведения, "РАЗРЕШЕННЫЕ", ""); // @Query-part-1, @Query-part-2
		Иначе
			ТекстЗапроса = ТекстЗапросаДопСведения;
		КонецЕсли;
	КонецЕсли;
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяОбъектаСДополнительнымиРеквизитами",
		ИмяОбъектаСоСвойствами + ".ДополнительныеРеквизиты");
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ИмяОбъектаСМетками", ИмяОбъектаСоСвойствами + ".Метки");
	
	Запрос.Параметры.Вставить("ОбъектыСоСвойствами", ОбъектыСоСвойствами);
	Запрос.Параметры.Вставить("Свойства", Свойства);
	Запрос.Текст = ТекстЗапроса;
	
	Результат = Запрос.Выполнить().Выгрузить();
	Результат.Колонки.Добавить("Представление");
	ФорматСвойств = ФорматСвойств(Свойства);
	РезультатСТекстовымиСтроками = Неопределено;
	ИндексСтроки = 0;
	Для каждого ЗначениеСвойства Из Результат Цикл
		ЗначениеСвойства.Представление = ПредставлениеЗначения(ЗначениеСвойства.Значение,
			КодЯзыка,
			ФорматСвойств[ЗначениеСвойства.Свойство]);
		
		ТекстоваяСтрока = ЗначениеСвойства.ТекстоваяСтрока;
		Если Не ПустаяСтрока(ТекстоваяСтрока) Тогда
			Если РезультатСТекстовымиСтроками = Неопределено Тогда
				РезультатСТекстовымиСтроками = Результат.Скопировать(,"Свойство, ВладелецСвойств, ИмяСвойства, Представление");
				РезультатСТекстовымиСтроками.Колонки.Добавить("Значение");
				РезультатСТекстовымиСтроками.ЗагрузитьКолонку(Результат.ВыгрузитьКолонку("Значение"), "Значение");
			КонецЕсли;
			РезультатСТекстовымиСтроками[ИндексСтроки].Значение = ТекстоваяСтрока;
		КонецЕсли;
		ИндексСтроки = ИндексСтроки + 1;
	КонецЦикла;
	
	Возврат ?(РезультатСТекстовымиСтроками <> Неопределено, РезультатСТекстовымиСтроками, Результат);
КонецФункции

// АПК:142-вкл

// Возвращает значение дополнительного свойства объекта.
//
// Параметры:
//  Объект   - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
//                           ДокументСсылка.ЗаказПокупателя, ...
//  Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - ссылка на
//                           дополнительный реквизит, значение которого нужно получить.
//           - Строка - имя дополнительного свойства.
//  КодЯзыка - Строка - если указано, то вместо значения дополнительного свойства будет
//                      возвращено его представление на указанном языке.
//
// Возвращаемое значение:
//  Произвольный - любое значение, допустимое для свойства.
//
Функция ЗначениеСвойства(Объект, Свойство, КодЯзыка = "") Экспорт
	
	ПолучатьРеквизиты = УправлениеСвойствамиСлужебный.ЭтоОбъектМетаданныхСоСвойствами(Объект.Метаданные(), "ДополнительныеРеквизиты");
	
	Результат = ЗначенияСвойств(Объект, ПолучатьРеквизиты, Истина, Свойство, КодЯзыка);
	Если Результат.Количество() = 1 Тогда
		Если ЗначениеЗаполнено(КодЯзыка) Тогда
			Возврат Результат[0].Представление;
		Иначе
			Возврат Результат[0].Значение;
		КонецЕсли;
	КонецЕсли;
КонецФункции

// Проверяет, есть ли у объекта свойство.
//
// Параметры:
//  ВладелецСвойств - ЛюбаяСсылка - например: СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//  Свойство        - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - проверяемое свойство.
//
// Возвращаемое значение:
//  Булево - если Истина, свойство у владельца есть.
//
Функция ПроверитьСвойствоУОбъекта(ВладелецСвойств, Свойство) Экспорт
	
	МассивСвойств = СвойстваОбъекта(ВладелецСвойств);
	
	Если МассивСвойств.Найти(Свойство) = Неопределено Тогда
		Возврат Ложь;
	Иначе
		Возврат Истина;
	КонецЕсли;
	
КонецФункции

// Записывает дополнительные реквизиты и сведения владельцу свойств.
// Изменения происходят в транзакции.
// 
// Параметры:
//  ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя и т.д.
//  ТаблицаСвойствИЗначений - ТаблицаЗначений:
//    * Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство владельца.
//    * Значение - Произвольный - любое значение, допустимое для свойства (указано в элементе свойства).
//
Процедура ЗаписатьСвойстваУОбъекта(ВладелецСвойств, ТаблицаСвойствИЗначений) Экспорт
	
	ТаблицаДопРеквизитов = Новый ТаблицаЗначений;
	ТаблицаДопРеквизитов.Колонки.Добавить("Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"));
	ТаблицаДопРеквизитов.Колонки.Добавить("Значение");
	ТаблицаДопРеквизитов.Колонки.Добавить("ТекстоваяСтрока");
	
	Свойства = ТаблицаСвойствИЗначений.ВыгрузитьКолонку("Свойство");
	ТипСвойстваСведение = ОбщегоНазначения.ЗначениеРеквизитаОбъектов(Свойства, "ЭтоДополнительноеСведение");
	
	ТаблицаДопСведений = ТаблицаДопРеквизитов.СкопироватьКолонки();
	
	Для Каждого СтрокаТаблицыСвойств Из ТаблицаСвойствИЗначений Цикл
		Если ТипСвойстваСведение[СтрокаТаблицыСвойств.Свойство] = Истина Тогда
			НоваяСтрока = ТаблицаДопСведений.Добавить();
		Иначе
			НоваяСтрока = ТаблицаДопРеквизитов.Добавить();
			
			Если ТипЗнч(СтрокаТаблицыСвойств.Значение) = Тип("Строка")
				И СтрДлина(СтрокаТаблицыСвойств.Значение) > 1024 Тогда
				НоваяСтрока.ТекстоваяСтрока = СтрокаТаблицыСвойств.Значение;
			КонецЕсли;
		КонецЕсли;
		ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТаблицыСвойств, "Свойство,Значение");
	КонецЦикла;
	
	ЕстьДопРеквизиты = ТаблицаДопРеквизитов.Количество() > 0;
	ЕстьДопСведения  = ТаблицаДопСведений.Количество() > 0;
	
	МассивСвойств = СвойстваОбъекта(ВладелецСвойств);
	
	МассивДопРеквизитов = Новый Массив;
	МассивДопСведений = Новый Массив;
	
	Для Каждого ДопСвойство Из МассивСвойств Цикл
		Если ДопСвойство.ЭтоДополнительноеСведение Тогда
			МассивДопСведений.Добавить(ДопСвойство);
		Иначе
			МассивДопРеквизитов.Добавить(ДопСвойство);
		КонецЕсли;
	КонецЦикла;
	
	НачатьТранзакцию();
	Попытка
		Если ЕстьДопРеквизиты Тогда
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить(ВладелецСвойств.Метаданные().ПолноеИмя());
			ЭлементБлокировки.УстановитьЗначение("Ссылка", ВладелецСвойств);
			Блокировка.Заблокировать();
			
			ВладелецСвойствОбъект = ВладелецСвойств.ПолучитьОбъект();
			ЗаблокироватьДанныеДляРедактирования(ВладелецСвойствОбъект.Ссылка);
			
			Для Каждого ДопРеквизит Из ТаблицаДопРеквизитов Цикл
				Если МассивДопРеквизитов.Найти(ДопРеквизит.Свойство) = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				МассивСтрок = ВладелецСвойствОбъект.ДополнительныеРеквизиты.НайтиСтроки(Новый Структура("Свойство", ДопРеквизит.Свойство));
				Если МассивСтрок.Количество() Тогда
					СтрокаСвойства = МассивСтрок[0];
				Иначе
					СтрокаСвойства = ВладелецСвойствОбъект.ДополнительныеРеквизиты.Добавить();
				КонецЕсли;
				ЗаполнитьЗначенияСвойств(СтрокаСвойства, ДопРеквизит, "Свойство,Значение,ТекстоваяСтрока");
			КонецЦикла;
			ВладелецСвойствОбъект.Записать();
		КонецЕсли;
		
		Если ЕстьДопСведения Тогда
			Для Каждого ДопСведение Из ТаблицаДопСведений Цикл
				Если МассивДопСведений.Найти(ДопСведение.Свойство) = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				Блокировка = Новый БлокировкаДанных;
				ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ДополнительныеСведения");
				ЭлементБлокировки.УстановитьЗначение("Объект", ВладелецСвойств);
				ЭлементБлокировки.УстановитьЗначение("Свойство", ДопСведение.Свойство);
				Блокировка.Заблокировать();
				
				МенеджерЗаписи = РегистрыСведений.ДополнительныеСведения.СоздатьМенеджерЗаписи();
				
				МенеджерЗаписи.Объект = ВладелецСвойств;
				МенеджерЗаписи.Свойство = ДопСведение.Свойство;
				МенеджерЗаписи.Значение = ДопСведение.Значение;
				
				МенеджерЗаписи.Записать(Истина);
			КонецЦикла;
			
		КонецЕсли;
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

// Проверяет, используются ли дополнительные реквизиты с объектом.
//
// Параметры:
//  ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//
// Возвращаемое значение:
//  Булево - если Истина, тогда дополнительные реквизиты используются.
//
Функция ИспользоватьДопРеквизиты(ВладелецСвойств) Экспорт
	
	МетаданныеВладельца = ВладелецСвойств.Метаданные();
	Возврат МетаданныеВладельца.ТабличныеЧасти.Найти("ДополнительныеРеквизиты") <> Неопределено
	      И МетаданныеВладельца <> Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений;
	
КонецФункции

// Проверяет, используются ли дополнительные сведения объектом.
//
// Параметры:
//  ВладелецСвойств - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//
// Возвращаемое значение:
//  Булево - если Истина, тогда дополнительные сведения используются.
//
Функция ИспользоватьДопСведения(ВладелецСвойств) Экспорт
	
	Возврат Метаданные.ОбщиеКоманды.Найти("ДополнительныеСведенияКоманднаяПанель") <> Неопределено
		И Метаданные.ОбщиеКоманды.ДополнительныеСведенияКоманднаяПанель.ТипПараметраКоманды.Типы().Найти(ТипЗнч(ВладелецСвойств)) <> Неопределено;
	
КонецФункции

// Проверяет доступность подсистемы для текущего пользователя.
//
// Возвращаемое значение:
//  Булево - Истина, если подсистема доступна.
//
Функция СвойстваДоступны() Экспорт
	Возврат ПравоДоступа("Чтение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений);
КонецФункции

// Возвращает представление значения дополнительного свойства объекта
// на требуемом языке.
//
// Параметры:
//  Объект   - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
//                           ДокументСсылка.ЗаказПокупателя, ...
//  Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - ссылка на
//                           дополнительный реквизит, значение которого нужно получить.
//           - Строка - имя дополнительного свойства.
//  КодЯзыка - Строка - код языка, на котором нужно получить представление.
//
// Возвращаемое значение:
//  Строка
//
Функция ПредставлениеЗначенияСвойства(Объект, Свойство, КодЯзыка = "") Экспорт
	Представление = ЗначениеСвойства(Объект, Свойство, КодЯзыка);
	Возврат Представление;
КонецФункции

// Возвращает значения дополнительных свойств объектов.
// Подходит для подстановки параметров при формировании печатных форм.
//
// Параметры:
//  ОбъектыСоСвойствами  - Массив      - объекты, для которых нужно получить значения дополнительных свойств.
//                       - ЛюбаяСсылка - ссылка на объект, например, СправочникСсылка.Номенклатура,
//                                       ДокументСсылка.ЗаказПокупателя, ...
//  КодЯзыка             - Строка - код языка, на котором нужно получить представление.
//
// Возвращаемое значение:
//  Соответствие из КлючИЗначение:
//   * Ключ - ЛюбаяСсылка - ссылка на объект.
//   * Значение - Структура:
//        * Ключ - Строка - имя свойства.
//        * Значение - Строка - представление свойства на переданном языке.
//
Функция ПредставленияЗначенийСвойств(ОбъектыСоСвойствами, КодЯзыка = "") Экспорт
	ЗначенияСвойств = ЗначенияСвойств(ОбъектыСоСвойствами, Истина, Истина, Неопределено, КодЯзыка);
	
	Результат = Новый Соответствие;
	
	Для Каждого ЗначениеСвойства Из ЗначенияСвойств Цикл
		Если Результат[ЗначениеСвойства.ВладелецСвойств] = Неопределено Тогда
			Результат.Вставить(ЗначениеСвойства.ВладелецСвойств, Новый Структура);
		КонецЕсли;
		
		ИмяСвойства = ЗначениеСвойства.ИмяСвойства;
		ПервыйСимвол = Лев(ЗначениеСвойства.ИмяСвойства, 1);
		Если СтрНайти("0123456789", ПервыйСимвол) > 0 Тогда
			ИмяСвойства = "_" + ИмяСвойства;
		КонецЕсли;
		Результат[ЗначениеСвойства.ВладелецСвойств].Вставить(ИмяСвойства, ЗначениеСвойства.Представление);
	КонецЦикла;
	
	Если ТипЗнч(ОбъектыСоСвойствами) = Тип("Массив") Тогда
		Для Каждого ОбъектСоСвойствами Из ОбъектыСоСвойствами Цикл
			Если Результат[ОбъектСоСвойствами] = Неопределено Тогда
				Результат[ОбъектСоСвойствами] = Новый Структура;
			КонецЕсли;
		КонецЦикла;
	Иначе
		Если Результат[ОбъектСоСвойствами] = Неопределено Тогда
			Результат[ОбъектСоСвойствами] = Новый Структура;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Метки

// Устанавливает видимость легенды меток в рамках сеанса работы.
// 
// Параметры:
//  Форма           - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
Процедура УстановитьВидимостьЛегендыМеток(Форма) Экспорт
	
	Если Форма.Элементы["ГруппаСкрываемаяЧастьЛегенды"].Видимость Тогда
		Форма.Элементы["ГруппаСкрываемаяЧастьЛегенды"].Видимость = Ложь;
		Форма.Элементы["ПоказатьЛегенду"].Картинка = БиблиотекаКартинок.СтрелкаВнизЗеленая;
		ВидимостьЛегендыМеток = Ложь;
	Иначе
		Форма.Элементы["ГруппаСкрываемаяЧастьЛегенды"].Видимость = Истина;
		Форма.Элементы["ПоказатьЛегенду"].Картинка = БиблиотекаКартинок.СтрелкаВправоЗеленая;
		ВидимостьЛегендыМеток = Истина;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	ТекущиеПараметры = Новый Соответствие(ПараметрыСеанса.ПараметрыКлиентаНаСервере);
	ТекущиеПараметры.Вставить("ВидимостьЛегендыМеток", ВидимостьЛегендыМеток);
	ПараметрыСеанса.ПараметрыКлиентаНаСервере = Новый ФиксированноеСоответствие(ТекущиеПараметры); 
	УстановитьПривилегированныйРежим(Ложь);
	ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("Свойства", "ВидимостьЛегендыМеток", ВидимостьЛегендыМеток);
	
КонецПроцедуры

// Заполняет/перезаполняет метки в форме владельца свойств.
//
// Параметры:
//  Форма              - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
//  Объект             - Неопределено - взять объект из реквизита формы "Объект".
//                     - СправочникОбъектИмяСправочника
//                     - ДокументОбъектИмяДокумента
//                     - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                     - БизнесПроцессОбъектИмяБизнесПроцесса
//                     - ЗадачаОбъектИмяЗадачи
//                     - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                     - ПланСчетовОбъектИмяПланаСчетов
//                     - ДанныеФормыСтруктура
//
//  ПроизвольныйОбъект - Булево - если Истина, тогда в форме нельзя редактировать метки.
//
Процедура ЗаполнитьМеткиОбъекта(Форма, Объект = Неопределено, ПроизвольныйОбъект = Ложь) Экспорт
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
	 ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		Возврат;
	КонецЕсли;
	
	ИмяЭлементаДляРазмещенияМеток = Форма.Свойства_ИмяЭлементаДляРазмещенияМеток;
	Если Не ЗначениеЗаполнено(ИмяЭлементаДляРазмещенияМеток) Тогда
		Возврат;
	КонецЕсли;
	
	Если Объект = Неопределено Тогда
		Если ПроизвольныйОбъект Тогда
			Возврат;
		КонецЕсли;
		ОписаниеОбъекта = Форма.Объект;
	Иначе
		ОписаниеОбъекта = Объект;
	КонецЕсли;
	
	Если Форма.Элементы.Найти("РедактироватьМетки") = Неопределено Тогда
		НовыйЭлемент = Форма.Элементы.Добавить("РедактироватьМетки", Тип("ДекорацияФормы"),
			Форма.Элементы[ИмяЭлементаДляРазмещенияМеток]);
		НовыйЭлемент.Вид = ВидДекорацииФормы.Картинка;
		НовыйЭлемент.Гиперссылка = Истина;
		НовыйЭлемент.Картинка = БиблиотекаКартинок.РедактироватьМетки;
		НовыйЭлемент.УстановитьДействие("Нажатие", "Подключаемый_СвойстваВыполнитьКоманду");
		НовыйЭлемент.Подсказка = НСтр("ru = 'Редактировать метки'");
	КонецЕсли;
	
	Метки = СвойстваПоВидуДополнительныхРеквизитов(
		ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить(),
		Перечисления.ВидыСвойств.Метки);
	Если Форма.Свойства_УстановленныеМетки.Количество() = 0 Тогда
		Форма.Свойства_УстановленныеМетки.ЗагрузитьЗначения(Метки);
	КонецЕсли;
	
	ГруппаМетки = Форма.Элементы[ИмяЭлементаДляРазмещенияМеток];
	ПодчиненныеЭлементы = ГруппаМетки.ПодчиненныеЭлементы;
	ИменаМетокНаУдаление = Новый Массив;
	Для каждого ПодчиненныйЭлемент Из ПодчиненныеЭлементы Цикл
		Если ПодчиненныйЭлемент = Форма.Элементы["РедактироватьМетки"] Тогда
			Продолжить;
		КонецЕсли;
		ИменаМетокНаУдаление.Добавить(ПодчиненныйЭлемент.Имя);
	КонецЦикла;
	
	Для каждого Метка Из ИменаМетокНаУдаление Цикл
		Форма.Элементы.Удалить(Форма.Элементы[Метка]);
	КонецЦикла;
	
	СкрытьМеток = 0;
	КоличествоМеток = Метки.Количество();
	МаксимумМетокНаФорме = Форма.ПараметрыСвойств.МаксимумМетокНаФорме;
	Если МаксимумМетокНаФорме <> Неопределено И МаксимумМетокНаФорме < КоличествоМеток Тогда
		СкрытьМеток = КоличествоМеток - МаксимумМетокНаФорме;
		КоличествоМеток = МаксимумМетокНаФорме;
	КонецЕсли;
	ВариантОтображенияМеток = Форма.ПараметрыСвойств.ВариантОтображенияМеток;
	
	ОтображеноМеток = 0;
	РеквизитыМеток = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(Метки,
		"Имя, ЦветСвойств, Наименование, ПометкаУдаления, Подсказка");
	Если ВариантОтображенияМеток = Перечисления.ВариантыОтображенияМеток.Надпись Тогда
		Для Индекс = 0 По КоличествоМеток - 1 Цикл
			Метка = РеквизитыМеток.Получить(Метки[Индекс]);
			Если Метка = Неопределено Или Метка.ПометкаУдаления Тогда
				Продолжить;
			КонецЕсли;
			НовыйЭлемент = Форма.Элементы.Добавить("Метка" + Метка.Имя, Тип("ДекорацияФормы"), ГруппаМетки);
			НовыйЭлемент.Вид = ВидДекорацииФормы.Надпись;
			НовыйЭлемент.ГоризонтальноеПоложение = ГоризонтальноеПоложениеЭлемента.Центр;
			НовыйЭлемент.Высота = 1;
			НовыйЭлемент.Заголовок = Метка.Наименование;
			НовыйЭлемент.ЦветТекста = Метаданные.ЭлементыСтиля.ЦветТекстаМетки.Значение;
			НовыйЭлемент.ЦветФона = ЭлементСтиляПоЦвету(Метка.ЦветСвойств);
			НовыйЭлемент.Шрифт = Метаданные.ЭлементыСтиля.ШрифтМеток.Значение;
			НовыйЭлемент.Подсказка = Метка.Подсказка;
			Если Не ПроизвольныйОбъект Тогда
				НовыйЭлемент.Гиперссылка = Истина;
				НовыйЭлемент.УстановитьДействие("Нажатие", "Подключаемый_СвойстваВыполнитьКоманду");
			КонецЕсли;
			ДлинаНаименования = СтрДлина(Метка.Наименование);
			Если ДлинаНаименования > 8 Тогда
				НовыйЭлемент.Ширина = ДлинаНаименования;
			Иначе
				НовыйЭлемент.Ширина = 8;
			КонецЕсли;
			ОтображеноМеток = ОтображеноМеток + 1;
		КонецЦикла;
	Иначе
		Для Индекс = 0 По КоличествоМеток - 1 Цикл
			Метка = РеквизитыМеток.Получить(Метки[Индекс]);
			Если Метка = Неопределено Или Метка.ПометкаУдаления Тогда
				Продолжить;
			КонецЕсли;
			НовыйЭлемент = Форма.Элементы.Добавить("Метка" + Метка.Имя, Тип("ДекорацияФормы"), ГруппаМетки);
			НовыйЭлемент.Вид = ВидДекорацииФормы.Картинка;
			Если Не ПроизвольныйОбъект Тогда
				НовыйЭлемент.Гиперссылка = Истина;
			КонецЕсли;
			НовыйЭлемент.Картинка = КартинкаМеткиПоЦвету(Метка.ЦветСвойств);
			НовыйЭлемент.УстановитьДействие("Нажатие", "Подключаемый_СвойстваВыполнитьКоманду");
			НовыйЭлемент.Подсказка = Метка.Наименование;
			НовыйЭлемент.Заголовок = Метка.Наименование;
			ОтображеноМеток = ОтображеноМеток + 1;
		КонецЦикла;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СкрытьМеток) Тогда
		НовыйЭлемент = Форма.Элементы.Добавить("ОстальныеМетки", Тип("ДекорацияФормы"), ГруппаМетки);
		НовыйЭлемент.Вид = ВидДекорацииФормы.Надпись;
		НовыйЭлемент.Гиперссылка = Истина;
		НовыйЭлемент.УстановитьДействие("Нажатие", "Подключаемый_СвойстваВыполнитьКоманду"); 
		НовыйЭлемент.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'и еще %1'"), СкрытьМеток);
		НовыйЭлемент.Подсказка = НСтр("ru = 'Остальные метки'");
	КонецЕсли;
	
	Если ПроизвольныйОбъект Или ОтображеноМеток <> 0 Тогда
		Форма.Элементы["РедактироватьМетки"].Видимость = Ложь;
	Иначе
		Форма.Элементы["РедактироватьМетки"].Видимость = Истина;
	КонецЕсли;
	
КонецПроцедуры

// Возвращает структуру параметров для отображения меток на форме.
//
// Возвращаемое значение:
//  Структура:
//    
//    * ИмяЭлементаДляРазмещенияМеток - Строка - имя группы формы, в которой будут размещены метки.
//    
//    * ИмяЭлементаДляРазмещенияЛегендыМеток - Строка - имя группы формы, в которой будет размещена легенда меток.
//    
//    * МаксимумМетокНаФорме - Число - максимальное количество отображаемых меток на форме. По умолчанию, ограничений нет.
//    
//    * ОтборМеток - Булево - возможность отбирать объекты в списке по меткам.
//    
//    * ВариантОтображенияМеток - ПеречислениеСсылка.ВариантыОтображенияМеток - вариант отображения меток на форме.
//            Миниатюрные цветные картинки для форм с небольшим количеством свободного места или
//            надписи с цветным фоном для быстрого ознакомления с текстом меток.
//            По умолчанию, используется вариант Картинка.
//    
//    * ВидОбъектов - Строка - полное имя объекта метаданных для отображения легенды меток в форме списка.
//
Функция ПараметрыОтображенияМеток() Экспорт
	
	ПараметрыОтображенияМеток = Новый Структура;
	ПараметрыОтображенияМеток.Вставить("ИмяЭлементаДляРазмещенияМеток", "");
	ПараметрыОтображенияМеток.Вставить("ИмяЭлементаДляРазмещенияЛегендыМеток", "");
	ПараметрыОтображенияМеток.Вставить("ВариантОтображенияМеток", Перечисления.ВариантыОтображенияМеток.Картинка);
	ПараметрыОтображенияМеток.Вставить("МаксимумМетокНаФорме");
	ПараметрыОтображенияМеток.Вставить("ОтборМеток", Ложь);
	ПараметрыОтображенияМеток.Вставить("ВидОбъектов", "");
	
	Возврат ПараметрыОтображенияМеток;
	
КонецФункции

// Возвращает свойства определенного вида.
//
// Параметры:
//  Свойства   - ТаблицаЗначений - таблица свойств.
//
//  ВидСвойств - ПеречислениеСсылка.ВидыСвойств - вид свойств, дополнительные реквизиты или метки.
//
// Возвращаемое значение:
//  Массив     - массив свойств определенного вида.
//
Функция СвойстваПоВидуДополнительныхРеквизитов(Свойства, ВидСвойств) Экспорт
	
	СвойстваПоВиду = Новый Массив;
	СписокСвойств = Свойства.ВыгрузитьКолонку("Свойство");
	ВидыСвойствОбъектов = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(СписокСвойств, "ВидСвойств");
	Если ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеРеквизиты Тогда
		Для Каждого Свойство Из СписокСвойств Цикл
			ВидСвойствОбъекта = ВидыСвойствОбъектов.Получить(Свойство);
			Если Не ЗначениеЗаполнено(ВидСвойствОбъекта) Тогда
				Продолжить;
			КонецЕсли;
			Если Не ЗначениеЗаполнено(ВидСвойствОбъекта.ВидСвойств)
				Или ВидСвойствОбъекта.ВидСвойств = ВидСвойств Тогда
				СвойстваПоВиду.Добавить(Свойство);
			КонецЕсли;
		КонецЦикла;
	ИначеЕсли ВидСвойств = Перечисления.ВидыСвойств.Метки Тогда
		Для Каждого Свойство Из СписокСвойств Цикл
			ВидСвойствОбъекта = ВидыСвойствОбъектов.Получить(Свойство);
			Если Не ЗначениеЗаполнено(ВидСвойствОбъекта) Тогда
				Продолжить;
			КонецЕсли;
			Если ВидСвойствОбъекта.ВидСвойств = ВидСвойств Тогда
				СвойстваПоВиду.Добавить(Свойство);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Возврат СвойстваПоВиду;
	
КонецФункции

// Возвращает признак наличия владельцев меток.
// 
// Возвращаемое значение:
//  Булево     - признак наличия владельцев меток.
//
Функция ЕстьВладельцыМеток() Экспорт
	
	ВладельцыМеток = Метаданные.ОпределяемыеТипы.ВладелецМеток.Тип.Типы();
	Если ВладельцыМеток.Количество() = 1 И ВладельцыМеток[0] = Тип("Строка") Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.

// 1. Обновляет наименования предопределенных наборов свойств,
// если они отличаются от текущих представлений соответствующих
// им объектов метаданных со свойствами.
// 2. Обновляет наименования не общих свойств, если у них
// уточнение отличается от наименования их набора.
// 3. Устанавливает пометку удаления у необщих свойств,
// если установлена пометка удаления их наборов.
//
Процедура ОбновитьНаименованияНаборовИСвойств() Экспорт
	
	ЗапросНаборов = Новый Запрос;
	ЗапросНаборов.Текст =
	"ВЫБРАТЬ
	|	Наборы.Ссылка КАК Ссылка,
	|	Наборы.Наименование КАК Наименование
	|ИЗ
	|	Справочник.НаборыДополнительныхРеквизитовИСведений КАК Наборы
	|ГДЕ
	|	Наборы.Предопределенный
	|	И Наборы.Родитель = ЗНАЧЕНИЕ(Справочник.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка)";
	
	ВыборкаНаборов = ЗапросНаборов.Выполнить().Выбрать();
	Пока ВыборкаНаборов.Следующий() Цикл
		
		НачатьТранзакцию();
		Попытка
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
			ЭлементБлокировки.УстановитьЗначение("Ссылка", ВыборкаНаборов.Ссылка);
			Блокировка.Заблокировать();
			
			Наименование = УправлениеСвойствамиСлужебный.НаименованиеПредопределенногоНабора(
				ВыборкаНаборов.Ссылка);
			
			Если ВыборкаНаборов.Наименование <> Наименование Тогда
				Объект = ВыборкаНаборов.Ссылка.ПолучитьОбъект();
				Объект.Наименование = Наименование;
				ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);
			КонецЕсли;
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ВызватьИсключение;
		КонецПопытки;
	КонецЦикла;
	
	ЗапросСвойств = Новый Запрос;
	ЗапросСвойств.Текст =
	"ВЫБРАТЬ
	|	Свойства.Ссылка КАК Ссылка,
	|	Свойства.НаборСвойств.ПометкаУдаления КАК ПометкаУдаленияНабора
	|ИЗ
	|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
	|ГДЕ
	|	ВЫБОР
	|			КОГДА Свойства.НаборСвойств = ЗНАЧЕНИЕ(Справочник.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка)
	|				ТОГДА ЛОЖЬ
	|			ИНАЧЕ ВЫБОР
	|					КОГДА Свойства.Наименование <> Свойства.Заголовок
	|						ТОГДА ИСТИНА
	|					ИНАЧЕ ЛОЖЬ
	|				КОНЕЦ
	|		КОНЕЦ";
	
	ВыборкаСвойств = ЗапросСвойств.Выполнить().Выбрать();
	Пока ВыборкаСвойств.Следующий() Цикл
		
		НачатьТранзакцию();
		Попытка
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения");
			ЭлементБлокировки.УстановитьЗначение("Ссылка", ВыборкаСвойств.Ссылка);
			Блокировка.Заблокировать();
		
			Объект = ВыборкаСвойств.Ссылка.ПолучитьОбъект(); // ПланВидовХарактеристикОбъект.ДополнительныеРеквизитыИСведения
			Объект.Наименование = Объект.Заголовок;
			Объект.ПометкаУдаления = ВыборкаСвойств.ПометкаУдаленияНабора;
			ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);
			
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ВызватьИсключение;
		КонецПопытки;
		
	КонецЦикла;
	
КонецПроцедуры

// Устанавливает параметры набора свойств.
//
// Параметры:
//  ИмяНабораСвойств - Строка - имя предопределенного набора свойств.
//  Параметры - см. СтруктураПараметровНабораСвойств
//
Процедура УстановитьПараметрыНабораСвойств(ИмяНабораСвойств, Параметры = Неопределено) Экспорт
	
	Если Параметры = Неопределено Тогда
		Параметры = СтруктураПараметровНабораСвойств();
	КонецЕсли;
	
	ЗаписатьОбъект = Ложь;
	НаборСвойств = НаборСвойствПоИмени(ИмяНабораСвойств);
	Если НаборСвойств = Неопределено Тогда
		НаборСвойств = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяНабораСвойств];
	КонецЕсли;
	
	НачатьТранзакцию();
	Попытка
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", НаборСвойств);
		Блокировка.Заблокировать();
		
		НаборСвойствОбъект = НаборСвойств.ПолучитьОбъект();
		Если НаборСвойствОбъект = Неопределено Тогда
			ОтменитьТранзакцию();
			Возврат;
		КонецЕсли;
		
		Для Каждого Параметр Из Параметры Цикл
			Если НаборСвойствОбъект[Параметр.Ключ] = Параметр.Значение Тогда
				Продолжить;
			КонецЕсли;
			ЗаписатьОбъект = Истина;
		КонецЦикла;
		
		Если ЗаписатьОбъект Тогда
			ЗаполнитьЗначенияСвойств(НаборСвойствОбъект, Параметры);
			ОбновлениеИнформационнойБазы.ЗаписатьДанные(НаборСвойствОбъект);
		КонецЕсли;
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

// Получает структуру параметров для набора свойств.
//
// Возвращаемое значение: 
//  Структура:
//     * Используется - Булево - признак использования набора свойств.
//                               Устанавливается в Ложь, например, если
//                               объект отключен функциональной опцией.
//
Функция СтруктураПараметровНабораСвойств() Экспорт
	
	Параметры = Новый Структура;
	Параметры.Вставить("Используется", Истина);
	Возврат Параметры;
	
КонецФункции

// Для использования в обработчиках обновления. Позволяет сохранить настройки форм
// при переходе на описание наборов свойств в процедуре
// УправлениеСвойствамиПереопределяемый.ПриПолученииПредопределенныхНаборовСвойств,
// если до этого они описывались в предопределенных элементах справочника
// НаборыДополнительныхРеквизитовИСведений.
//
Процедура ВосстановитьНастройкиФормСДополнительнымиРеквизитами() Экспорт
	
	Наборы = Новый Соответствие;
	ИменаПредопределенныхНаборов = Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений.ПолучитьИменаПредопределенных();
	УстаревшиеПредопределенныеЭлементы = Новый Массив;
	Для Каждого ИмяПредопределенногоНабора Из ИменаПредопределенныхНаборов Цикл
		Если Не СтрНачинаетсяС(ИмяПредопределенногоНабора, "Удалить") Тогда
			Продолжить;
		КонецЕсли;
		
		УстаревшиеПредопределенныеЭлементы.Добавить(ИмяПредопределенногоНабора);
	КонецЦикла;
	
	ЗапросДочернихНаборов = Новый Запрос;
	ЗапросДочернихНаборов.Текст =
		"ВЫБРАТЬ
		|	НаборыДополнительныхРеквизитовИСведений.Ссылка КАК Ссылка,
		|	НаборыДополнительныхРеквизитовИСведений.Родитель КАК Родитель
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений КАК НаборыДополнительныхРеквизитовИСведений
		|ГДЕ
		|	НаборыДополнительныхРеквизитовИСведений.ИмяПредопределенногоНабора = """"
		|	И НаборыДополнительныхРеквизитовИСведений.Родитель <> ЗНАЧЕНИЕ(Справочник.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка)";
	ВсеДочерниеНаборы = ЗапросДочернихНаборов.Выполнить().Выгрузить();
	ВсеДочерниеНаборы.Индексы.Добавить("Ссылка");
	
	ЗапросПредопределенныхНаборов = Новый Запрос;
	ЗапросПредопределенныхНаборов.УстановитьПараметр("ИмяПредопределенныхДанных", УстаревшиеПредопределенныеЭлементы);
	ЗапросПредопределенныхНаборов.Текст =
		"ВЫБРАТЬ
		|	НаборыДополнительныхРеквизитовИСведений.Ссылка КАК Ссылка,
		|	НаборыДополнительныхРеквизитовИСведений.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений КАК НаборыДополнительныхРеквизитовИСведений
		|ГДЕ
		|	НаборыДополнительныхРеквизитовИСведений.ЭтоГруппа = ЛОЖЬ
		|	И НаборыДополнительныхРеквизитовИСведений.ИмяПредопределенныхДанных В(&ИмяПредопределенныхДанных)";
	ТаблицаПредопределенных = ЗапросПредопределенныхНаборов.Выполнить().Выгрузить();
	Для Каждого Строка Из ТаблицаПредопределенных Цикл
		Попытка
			ДлинаПрефикса = СтрДлина("Удалить");
			ИмяНабора = Сред(Строка.ИмяПредопределенныхДанных, ДлинаПрефикса + 1, СтрДлина(Строка.ИмяПредопределенныхДанных) - ДлинаПрефикса);
			
			ИдентификаторСсылки = Строка(Строка.Ссылка.УникальныйИдентификатор());
			Если СтрЗаканчиваетсяНа(ИмяНабора, "_Общие") Тогда 
				Дочерние = Новый Массив;
				ИмяНабора     = СтрЗаменить(ИмяНабора, "_Общие", "");
				НаборРодитель = НаборСвойствПоИмени(ИмяНабора);
				ОтборСтрок = Новый Структура("Родитель", НаборРодитель);
				ДочерниеНаборы = ВсеДочерниеНаборы.НайтиСтроки(ОтборСтрок);
				Для Каждого ДочернийНабор Из ДочерниеНаборы Цикл
					ИдентификаторСсылкиДочернего = Строка(ДочернийНабор.Ссылка.УникальныйИдентификатор());
					
					ИдентификаторыНаборов = Новый СписокЗначений;
					ИдентификаторыНаборов.Добавить(ИдентификаторСсылки);
					ИдентификаторыНаборов.Добавить(ИдентификаторСсылкиДочернего);
					ИдентификаторыНаборов.СортироватьПоЗначению();
					
					СтрокаИдентификаторов = "";
					Для Каждого ЭлементСписка Из ИдентификаторыНаборов Цикл
						СтрокаИдентификаторов = СтрокаИдентификаторов + СтрЗаменить(ЭлементСписка.Значение, "-", "");
					КонецЦикла;
					
					КонтрольнаяСумма = ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрокаИдентификаторов);
					Дочерние.Добавить("КлючНаборовСвойств" + КонтрольнаяСумма);
				КонецЦикла;
				Наборы.Вставить(ИмяНабора, Дочерние);
			Иначе
				КонтрольнаяСумма = ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрЗаменить(ИдентификаторСсылки, "-", ""));
				Наборы.Вставить(ИмяНабора, "КлючНаборовСвойств" + КонтрольнаяСумма + "," + ИдентификаторСсылки);
			КонецЕсли;
		Исключение
			// Обработка исключения не требуется, отсутствует предопределенный элемент в данных.
			Продолжить;
		КонецПопытки;
	КонецЦикла;
	
	Настройки = УправлениеСвойствамиСлужебный.ЧтениеНастроекИзХранилища(ХранилищеСистемныхНастроек);
	Для Каждого Настройка Из Настройки Цикл
		КлючОбъекта = Настройка.КлючОбъекта;
		КлючОбъектаЧастями = СтрРазделить(КлючОбъекта, ".", Ложь);
		Если КлючОбъектаЧастями.Количество() < 3 Тогда
			Продолжить;
		КонецЕсли;
		ИмяНабора      = КлючОбъектаЧастями[0] + "_" + КлючОбъектаЧастями[1];
		КлючНазначения = Наборы[ИмяНабора];
		Если КлючНазначения = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если ТипЗнч(КлючНазначения) = Тип("Массив") Тогда
			Для Каждого Элемент Из КлючНазначения Цикл
				УправлениеСвойствамиСлужебный.ПеренестиНастройку(Настройка, Элемент, ИмяНабора);
			КонецЦикла;
		Иначе 
			КлючНазначенияЧастями = СтрРазделить(КлючНазначения, ",");
			УправлениеСвойствамиСлужебный.ПеренестиНастройку(Настройка, КлючНазначенияЧастями[0], ИмяНабора, КлючНазначенияЧастями[1]);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

#Область УстаревшиеПроцедурыИФункции

// Устарела. Следует использовать ЗначенияСвойств или ЗначенияСвойства.
// Возвращает значения дополнительных свойств объекта.
//
// Параметры:
//  ВладелецСвойств      - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//  ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты.
//  ПолучатьДопСведения  - Булево - в результат включать дополнительные сведения.
//  МассивСвойств        - Массив из ПланВидовХарактеристикСсылка - дополнительные реквизиты, значения
//                            которых следует получить.
//                       - Неопределено - получить значения всех свойств владельца.
// Возвращаемое значение:
//  ТаблицаЗначений:
//    * Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство владельца.
//    * Значение - Произвольный - значения любого типа из описания типов свойства объекта метаданных:
//                  "Метаданные.ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Тип".
//
Функция ПолучитьЗначенияСвойств(ВладелецСвойств,
                                ПолучатьДопРеквизиты = Истина,
                                ПолучатьДопСведения = Истина,
                                МассивСвойств = Неопределено) Экспорт
	
	Возврат ЗначенияСвойств(ВладелецСвойств, ПолучатьДопРеквизиты, ПолучатьДопСведения, МассивСвойств);
	
КонецФункции

// Устарела. Следует использовать СвойстваОбъекта.
// Возвращает свойства владельца.
//
// Параметры:
//  ВладелецСвойств      - ЛюбаяСсылка - например, СправочникСсылка.Номенклатура, ДокументСсылка.ЗаказПокупателя, ...
//  ПолучатьДопРеквизиты - Булево - в результат включать дополнительные реквизиты.
//  ПолучатьДопСведения  - Булево - в результат включать дополнительные сведения.
//
// Возвращаемое значение:
//  Массив из ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - если есть.
//
Функция ПолучитьСписокСвойств(ВладелецСвойств, ПолучатьДопРеквизиты = Истина, ПолучатьДопСведения = Истина) Экспорт
	Возврат СвойстваОбъекта(ВладелецСвойств, ПолучатьДопРеквизиты, ПолучатьДопСведения);
КонецФункции

// Возвращает перечисляемые значения указанного свойства.
//
// Параметры:
//  Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство для
//             которого нужно получить перечисляемые значения.
// 
// Возвращаемое значение:
//  Массив из СправочникСсылка.ЗначенияСвойствОбъектов, СправочникСсылка.ЗначенияСвойствОбъектовИерархия - значения
//      свойства, если есть.
//
Функция ПолучитьСписокЗначенийСвойств(Свойство) Экспорт
	
	Возврат УправлениеСвойствамиСлужебный.ДополнительныеЗначенияСвойства(Свойство);
	
КонецФункции

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

////////////////////////////////////////////////////////////////////////////////
// Вспомогательные процедуры и функции.

// Создает основные реквизиты, команды, элементы в форме владельца свойств.
Процедура СоздатьОсновныеОбъектыФормы(Форма, Контекст, СоздатьОписаниеДополнительныхРеквизитов)
	
	ИмяЭлементаДляРазмещения   = Контекст.ИмяЭлементаДляРазмещения;
	ИмяЭлементаКоманднойПанели = Контекст.ИмяЭлементаКоманднойПанели;
	ОтложеннаяИнициализация    = Контекст.ОтложеннаяИнициализация;
	ПроизвольныйОбъект         = Контекст.ПроизвольныйОбъект;
	
	ИмяЭлементаДляРазмещенияМеток        = Контекст.ПараметрыОтображенияМеток.ИмяЭлементаДляРазмещенияМеток;
	ИмяЭлементаДляРазмещенияЛегендыМеток = Контекст.ПараметрыОтображенияМеток.ИмяЭлементаДляРазмещенияЛегендыМеток;
	ВариантОтображенияМеток              = Контекст.ПараметрыОтображенияМеток.ВариантОтображенияМеток;
	МаксимумМетокНаФорме                 = Контекст.ПараметрыОтображенияМеток.МаксимумМетокНаФорме;
	ВидОбъектов                          = Контекст.ПараметрыОтображенияМеток.ВидОбъектов;
	ОтборМеток                           = Контекст.ПараметрыОтображенияМеток.ОтборМеток;
	
	Реквизиты = Новый Массив;
	
	// Проверка значения функциональной опции "Использование свойств".
	ОпцияИспользоватьСвойства = Форма.ПолучитьФункциональнуюОпциюФормы("ИспользоватьДополнительныеРеквизитыИСведения");
	РеквизитИспользоватьСвойства = Новый РеквизитФормы("Свойства_ИспользоватьСвойства", Новый ОписаниеТипов("Булево"));
	Реквизиты.Добавить(РеквизитИспользоватьСвойства);
	РеквизитСкрытьУдаленные = Новый РеквизитФормы("Свойства_СкрытьУдаленные", Новый ОписаниеТипов("Булево"));
	Реквизиты.Добавить(РеквизитСкрытьУдаленные);
	// Дополнительные параметры подсистемы свойства.
	ДобавитьРеквизитПараметрыСвойств = Истина;
	Для Каждого Реквизит Из Форма.ПолучитьРеквизиты() Цикл
		Если Реквизит.Имя = "ПараметрыСвойств" Тогда
			ДобавитьРеквизитПараметрыСвойств = Ложь;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Если ДобавитьРеквизитПараметрыСвойств Тогда
		РеквизитПараметрыСвойств = Новый РеквизитФормы("ПараметрыСвойств", Новый ОписаниеТипов());
		Реквизиты.Добавить(РеквизитПараметрыСвойств);
	КонецЕсли;
	Если ОпцияИспользоватьСвойства Тогда
		
		РеквизитИспользоватьДопРеквизиты = Новый РеквизитФормы("Свойства_ИспользоватьДопРеквизиты", Новый ОписаниеТипов("Булево"));
		Реквизиты.Добавить(РеквизитИспользоватьДопРеквизиты);
		
		Если СоздатьОписаниеДополнительныхРеквизитов Тогда
			
			// Добавление реквизита содержащего используемые наборы дополнительных реквизитов.
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Свойства_НаборыДополнительныхРеквизитовОбъекта", Новый ОписаниеТипов("СписокЗначений")));
			
			// Добавление реквизита описания создаваемых реквизитов и элементов формы.
			ИмяОписания = "Свойства_ОписаниеДополнительныхРеквизитов";
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				ИмяОписания, Новый ОписаниеТипов("ТаблицаЗначений")));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ИмяРеквизитаЗначение", Новый ОписаниеТипов("Строка"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"),
					ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ВладелецДополнительныхЗначений", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"),
					ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ТипЗначения", Новый ОписаниеТипов("ОписаниеТипов"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"МногострочноеПолеВвода", Новый ОписаниеТипов("Число"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Удалено", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ЗаполнятьОбязательно", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Доступен", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Виден", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Наименование", Новый ОписаниеТипов("Строка"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ЭлементФормыДобавлен", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ВыводитьВВидеГиперссылки", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"СтрокаСсылочногоТипа", Новый ОписаниеТипов("Булево"), ИмяОписания));
			
			// Добавление реквизита описания зависимых реквизитов.
			ТаблицаЗависимыхРеквизитов = "Свойства_ОписаниеЗависимыхДополнительныхРеквизитов";
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				ТаблицаЗависимыхРеквизитов, Новый ОписаниеТипов("ТаблицаЗначений")));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ИмяРеквизитаЗначение", Новый ОписаниеТипов("Строка"), ТаблицаЗависимыхРеквизитов));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Доступен", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"УсловиеДоступности", Новый ОписаниеТипов(), ТаблицаЗависимыхРеквизитов));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Виден", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
				
			Реквизиты.Добавить(Новый РеквизитФормы(
				"УсловиеВидимости", Новый ОписаниеТипов(), ТаблицаЗависимыхРеквизитов));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ЗаполнятьОбязательно", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"УсловиеОбязательностиЗаполнения", Новый ОписаниеТипов(), ТаблицаЗависимыхРеквизитов));
			
			Реквизиты.Добавить(Новый РеквизитФормы(
				"ВыводитьВВидеГиперссылки", Новый ОписаниеТипов("Булево"), ТаблицаЗависимыхРеквизитов));
			
			// Добавление реквизита содержащего элементы создаваемых групп дополнительных реквизитов.
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Свойства_ЭлементыГруппДополнительныхРеквизитов", Новый ОписаниеТипов("СписокЗначений")));
			
			// Добавление реквизита с именем элемента в котором будут размещаться поля ввода.
			Реквизиты.Добавить(Новый РеквизитФормы(
				"Свойства_ИмяЭлементаДляРазмещения", Новый ОписаниеТипов()));
			
			// Метки
			Реквизиты.Добавить(Новый РеквизитФормы("Свойства_ИмяЭлементаДляРазмещенияМеток",
				Новый ОписаниеТипов("Строка")));
			
			Реквизиты.Добавить(Новый РеквизитФормы("Свойства_УстановленныеМетки",
				Новый ОписаниеТипов("СписокЗначений")));
			
			Если ПроизвольныйОбъект Тогда
				Реквизиты.Добавить(Новый РеквизитФормы("Свойства_ИмяЭлементаДляРазмещенияЛегендыМеток",
					Новый ОписаниеТипов("Строка")));
				
				// Добавление реквизита описания создаваемых меток.
				ИмяОписания = "Свойства_ОписаниеЛегендыМеток";
				Реквизиты.Добавить(Новый РеквизитФормы(ИмяОписания, Новый ОписаниеТипов("ТаблицаЗначений")));
				
				Реквизиты.Добавить(Новый РеквизитФормы("Метка",
					Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"), ИмяОписания));
				
				Реквизиты.Добавить(Новый РеквизитФормы("ИмяМетки", Новый ОписаниеТипов("Строка"), ИмяОписания));
				
				Если ОтборМеток Тогда
					Реквизиты.Добавить(Новый РеквизитФормы("ОтборПоМетке", Новый ОписаниеТипов("Булево"), ИмяОписания));
				КонецЕсли;
			КонецЕсли;
			
			// Добавление команды формы, если установлена роль "ДобавлениеИзменениеДополнительныхРеквизитовИСведений" или это
			// полноправный пользователь.
			Если ПравоДоступа("Изменение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений) Тогда
				// Добавление команды.
				Команда = Форма.Команды.Добавить("РедактироватьСоставДополнительныхРеквизитов");
				Команда.Заголовок = НСтр("ru = 'Изменить состав дополнительных реквизитов'");
				Команда.Действие = "Подключаемый_СвойстваВыполнитьКоманду";
				Команда.Подсказка = НСтр("ru = 'Изменить состав дополнительных реквизитов'");
				Команда.Картинка = БиблиотекаКартинок.НастройкаСписка;
				
				Кнопка = Форма.Элементы.Добавить(
					"РедактироватьСоставДополнительныхРеквизитов",
					Тип("КнопкаФормы"),
					?(ИмяЭлементаКоманднойПанели = "",
						Форма.КоманднаяПанель,
						Форма.Элементы[ИмяЭлементаКоманднойПанели]));
				
				Кнопка.ПоложениеВКоманднойПанели = ПоложениеКнопкиВКоманднойПанели.ВДополнительномПодменю;
				Кнопка.ИмяКоманды = "РедактироватьСоставДополнительныхРеквизитов";
			КонецЕсли;
			
			Команда = Форма.Команды.Добавить("РедактироватьГиперссылкуРеквизита");
			Команда.Заголовок   = НСтр("ru = 'Начать/закончить редактирование'");
			Команда.Действие    = "Подключаемый_СвойстваВыполнитьКоманду";
			Команда.Подсказка   = НСтр("ru = 'Начать/закончить редактирование'");
			Команда.Картинка    = БиблиотекаКартинок.Изменить;
			Команда.Отображение = ОтображениеКнопки.Картинка;
		КонецЕсли;
	КонецЕсли;
	
	Форма.ИзменитьРеквизиты(Реквизиты);
	
	Форма.Свойства_ИспользоватьСвойства = ОпцияИспользоватьСвойства;
	
	Форма.ПараметрыСвойств = Новый Структура;
	Если ОтложеннаяИнициализация Тогда
		// Если свойства не используются, признак выполнения отложенной инициализации
		// взводится в истину.
		Значение = ?(ОпцияИспользоватьСвойства, Ложь, Истина);
		Форма.ПараметрыСвойств.Вставить("ВыполненаОтложеннаяИнициализация", Значение);
	КонецЕсли;
	
	Если ОпцияИспользоватьСвойства Тогда
		Форма.Свойства_ИспользоватьДопРеквизиты = СоздатьОписаниеДополнительныхРеквизитов;
	КонецЕсли;
	
	Если ОпцияИспользоватьСвойства И СоздатьОписаниеДополнительныхРеквизитов Тогда
		Форма.Свойства_ИмяЭлементаДляРазмещения = ИмяЭлементаДляРазмещения;
		
		Форма.Свойства_ИмяЭлементаДляРазмещенияМеток = ИмяЭлементаДляРазмещенияМеток;
		Форма.ПараметрыСвойств.Вставить("ВариантОтображенияМеток", ВариантОтображенияМеток);
		Форма.ПараметрыСвойств.Вставить("МаксимумМетокНаФорме", МаксимумМетокНаФорме);
		
		Если ПроизвольныйОбъект Тогда
			Форма.Свойства_ИмяЭлементаДляРазмещенияЛегендыМеток = ИмяЭлементаДляРазмещенияЛегендыМеток;
			
			Форма.ПараметрыСвойств.Вставить("ВидОбъектов", ВидОбъектов);
			Форма.ПараметрыСвойств.Вставить("ОтборМеток", ОтборМеток);
			
			Команда = Форма.Команды.Добавить("ЛегендаМеток");
			Команда.Действие = "Подключаемый_УстановитьВидимостьЛегендыМеток";
			Команда.Картинка = БиблиотекаКартинок.Метка;
			Команда.Отображение = ОтображениеКнопки.КартинкаИТекст;
		КонецЕсли;
	КонецЕсли;
	
	// Если дополнительные реквизиты расположены на отдельной странице, включена
	// отложенная инициализация и свойства включены, то в страницу размещается пустая декорация.
	// Декорация удаляется автоматически при переключении на закладку.
	// Также блокируется возможность перемещения дополнительных реквизитов из группы.
	Если ОпцияИспользоватьСвойства
		И ОтложеннаяИнициализация
		И ИмяЭлементаДляРазмещения <> "" Тогда
		Форма.ПараметрыСвойств.Вставить("КоллекцияДекораций");
		Форма.ПараметрыСвойств.КоллекцияДекораций = Новый Массив;
		
		Форма.ПараметрыСвойств.Вставить("ДобавленаПустаяДекорация", Истина);
		Если ТипЗнч(ИмяЭлементаДляРазмещения ) = Тип("СписокЗначений") Тогда
			Индекс = 0;
			Для Каждого ГруппаРазмещения Из ИмяЭлементаДляРазмещения Цикл
				ПодготовитьФормуДляОтложеннойИнициализации(Форма, ГруппаРазмещения.Представление, Индекс);
				Индекс = Индекс + 1;
			КонецЦикла;
		Иначе
			ПодготовитьФормуДляОтложеннойИнициализации(Форма, ИмяЭлементаДляРазмещения, "");
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

// Добавляет на форму защиту-предупреждение от перемещения группы дополнительных реквизитов
// при включенной отложенной инициализации.
// 
// Параметры:
//  Форма - ФормаКлиентскогоПриложения:
//     * ПараметрыСвойств - Структура:
//        ** КоллекцияДекораций - Массив
//  ИмяЭлементаДляРазмещения - Строка
//  Индекс - Число
//
Процедура ПодготовитьФормуДляОтложеннойИнициализации(Форма, ИмяЭлементаДляРазмещения, Индекс)
	
	ГруппаФормы = Форма.Элементы[ИмяЭлементаДляРазмещения];
	Если ГруппаФормы.Вид <> ВидГруппыФормы.Страница Тогда
		Родитель = СтраницаРодитель(ГруппаФормы);
	Иначе
		Родитель = ГруппаФормы;
	КонецЕсли;
	
	Если Родитель <> Неопределено
		И Не Форма.ПараметрыСвойств.Свойство(Родитель.Имя) Тогда
		ИмяДекорации = "Свойства_ПустаяДекорация" + Индекс;
		Форма.ПараметрыСвойств.КоллекцияДекораций.Добавить(ИмяДекорации);
		Декорация = Форма.Элементы.Добавить(ИмяДекорации, Тип("ДекорацияФормы"), ГруппаФормы);
		
		ГруппаСтраниц = Родитель.Родитель;
		ЗаголовокСтраницы = ?(ЗначениеЗаполнено(Родитель.Заголовок), Родитель.Заголовок, Родитель.Имя);
		ЗаголовокГруппыСтраниц = ?(ЗначениеЗаполнено(ГруппаСтраниц.Заголовок), ГруппаСтраниц.Заголовок, ГруппаСтраниц.Имя);
		
		ПредупреждениеОРазмещении = НСтр("ru = 'Для отображения дополнительных реквизитов разместите группу ""%1"" не первым элементом (после любой другой группы) в группе ""%2"" (меню Еще - Изменить форму).'");
		ПредупреждениеОРазмещении = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ПредупреждениеОРазмещении,
			ЗаголовокСтраницы, ЗаголовокГруппыСтраниц);
		ТекстПодсказки = НСтр("ru = 'Также можно установить стандартные настройки формы:
			|   • в меню Еще выбрать пункт Изменить форму...;
			|   • в открывшейся форме ""Настройка формы"" в меню Еще выбрать пункт ""Установить стандартные настройки"".'");
			
		Декорация.ОтображениеПодсказки = ОтображениеПодсказки.Кнопка;
		Декорация.Заголовок  = ПредупреждениеОРазмещении;
		Декорация.Подсказка  = ТекстПодсказки;
		Декорация.ЦветТекста = ЦветаСтиля.ПоясняющийОшибкуТекст;
		
		// Страница, на которой размещаются дополнительные реквизиты.
		Форма.ПараметрыСвойств.Вставить(Родитель.Имя);
	КонецЕсли;
	
	ГруппаФормы.РазрешитьИзменениеСостава = Ложь;
	
КонецПроцедуры

// Заполняет легенду меток в форме владельца свойств.
//
// Параметры:
//  Форма              - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
//  Объект             - Неопределено - взять объект из реквизита формы "Объект".
//                     - СправочникОбъектИмяСправочника
//                     - ДокументОбъектИмяДокумента
//                     - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                     - БизнесПроцессОбъектИмяБизнесПроцесса
//                     - ЗадачаОбъектИмяЗадачи
//                     - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                     - ПланСчетовОбъектИмяПланаСчетов
//                     - ДанныеФормыСтруктура
//
Процедура ЗаполнитьЛегендуМеток(Форма, Объект)
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
	 ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		Возврат;
	КонецЕсли;
	
	ИмяЭлементаДляРазмещенияЛегендыМеток = Форма.Свойства_ИмяЭлементаДляРазмещенияЛегендыМеток;
	Если Не ЗначениеЗаполнено(ИмяЭлементаДляРазмещенияЛегендыМеток) Тогда
		Возврат;
	КонецЕсли;
	
	Метки = УправлениеСвойствамиСлужебный.СписокСвойствДляВидаОбъектов(
		Форма.ПараметрыСвойств.ВидОбъектов, "Метки").ВыгрузитьКолонку("Свойство");
	Если Метки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ВидимостьЛегендыМеток = ХранилищеОбщихНастроек.Загрузить("Свойства", "ВидимостьЛегендыМеток");
	
	Если ВидимостьЛегендыМеток = Неопределено Тогда
		ВидимостьЛегендыМеток = Ложь;
		ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("Свойства", "ВидимостьЛегендыМеток", ВидимостьЛегендыМеток);
	КонецЕсли;
	
	НовыйЭлемент = Форма.Элементы.Добавить("ПоказатьЛегенду", Тип("ДекорацияФормы"),
		Форма.Элементы[ИмяЭлементаДляРазмещенияЛегендыМеток]);
	НовыйЭлемент.Вид = ВидДекорацииФормы.Картинка;
	НовыйЭлемент.Гиперссылка = Истина;
	НовыйЭлемент.УстановитьДействие("Нажатие", "Подключаемый_УстановитьВидимостьЛегендыМеток");
	Если ВидимостьЛегендыМеток Тогда
		НовыйЭлемент.Картинка = БиблиотекаКартинок.СтрелкаВправоЗеленая;
	Иначе
		НовыйЭлемент.Картинка = БиблиотекаКартинок.СтрелкаВнизЗеленая;
	КонецЕсли;
	
	ГруппаСкрываемаяЧастьЛегенды = Форма.Элементы.Добавить("ГруппаСкрываемаяЧастьЛегенды", Тип("ГруппаФормы"),
		Форма.Элементы[ИмяЭлементаДляРазмещенияЛегендыМеток]);
	ГруппаСкрываемаяЧастьЛегенды.Вид = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаСкрываемаяЧастьЛегенды.Видимость = ВидимостьЛегендыМеток; 
	ГруппаСкрываемаяЧастьЛегенды.ОтображатьЗаголовок = Ложь;
	ГруппаСкрываемаяЧастьЛегенды.Группировка = Форма.Элементы[ИмяЭлементаДляРазмещенияЛегендыМеток].Группировка;
	
	ОтборМеток = Форма.ПараметрыСвойств.ОтборМеток;
	РеквизитыМеток = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(Метки,
		"Ссылка, Имя, Наименование, ЦветСвойств, ПометкаУдаления");
	Если ОтборМеток Тогда
		Реквизиты = Новый Массив;
		Для Каждого Метка Из Метки Цикл
			РеквизитыМетки = РеквизитыМеток.Получить(Метка);
			Если РеквизитыМетки = Неопределено Тогда
				Продолжить;
			КонецЕсли;
			Реквизиты.Добавить(Новый РеквизитФормы("ОтборМетка_" + РеквизитыМетки.Имя,
				Новый ОписаниеТипов("Булево")));
		КонецЦикла;
		Форма.ИзменитьРеквизиты(Реквизиты);
	КонецЕсли;
	
	Для Каждого Метка Из Метки Цикл
		Метка = РеквизитыМеток.Получить(Метка);
		Если Метка = Неопределено Или Метка.ПометкаУдаления Тогда
			Продолжить;
		КонецЕсли;
		
		Группа = Форма.Элементы.Добавить("Группа" + Метка.Имя, Тип("ГруппаФормы"), ГруппаСкрываемаяЧастьЛегенды);
		Группа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
		Группа.ОтображатьЗаголовок = Ложь;
		Группа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
		
		МеткаЛегенды = Форма.Свойства_ОписаниеЛегендыМеток.Добавить();
		МеткаЛегенды.Метка = Метка.Ссылка;
		МеткаЛегенды.ИмяМетки = Метка.Имя;
		
		Если ОтборМеток Тогда
			НовыйЭлемент = Форма.Элементы.Добавить("ОтборМетка_" + Метка.Имя, Тип("ПолеФормы"), Группа);
			НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
			НовыйЭлемент.ПутьКДанным = "ОтборМетка_" + Метка.Имя;
			НовыйЭлемент.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
			НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ОбработчикОтбораПоМеткам");
		КонецЕсли;
		
		НовыйЭлемент = Форма.Элементы.Добавить("Легенда_" + Метка.Имя, Тип("ДекорацияФормы"), Группа);
		НовыйЭлемент.Вид = ВидДекорацииФормы.Картинка;
		НовыйЭлемент.Картинка = КартинкаМеткиПоЦвету(Метка.ЦветСвойств);
		НовыйЭлемент.Подсказка = Метка.Наименование;
		НовыйЭлемент.ОтображениеПодсказки = ОтображениеПодсказки.ОтображатьСправа;
	КонецЦикла;
	
КонецПроцедуры

Функция СтраницаРодитель(ГруппаФормы)
	
	Родитель = ГруппаФормы.Родитель;
	Если ТипЗнч(Родитель) = Тип("ГруппаФормы") Тогда
		Родитель.РазрешитьИзменениеСостава = Ложь;
		Если Родитель.Вид = ВидГруппыФормы.Страница Тогда
			Возврат Родитель;
		Иначе
			Возврат СтраницаРодитель(Родитель);
		КонецЕсли;
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Процедура ОбновитьКлючНазначенияФормы(Форма, КлючНазначения)
	
	Если КлючНазначения = Неопределено Тогда
		КлючНазначения = КлючНаборовСвойств(Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
	КонецЕсли;
	
	Если ПустаяСтрока(КлючНазначения) Тогда
		Возврат;
	КонецЕсли;
	
	НачалоКлюча = "КлючНаборовСвойств";
	КлючНаборовСвойств = НачалоКлюча + Лев(КлючНазначения + "00000000000000000000000000000000", 32);
	
	НовыйКлюч = НовыйКлючНазначения(Форма.КлючНазначенияИспользования, НачалоКлюча, КлючНаборовСвойств);
	Если НовыйКлюч <> Неопределено Тогда
		Форма.КлючНазначенияИспользования = НовыйКлюч;
	КонецЕсли;
	
КонецПроцедуры

Функция РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, Параметры)
	ПараметрыУсловия = Новый Структура;
	ПараметрыУсловия.Вставить("ЗначенияПараметров", Параметры.ЗначенияПараметров);
	ПараметрыУсловия.Вставить("Форма", Форма);
	ПараметрыУсловия.Вставить("ОписаниеОбъекта", ОписаниеОбъекта);
	
	Возврат ОбщегоНазначения.ВычислитьВБезопасномРежиме(Параметры.КодУсловия, ПараметрыУсловия);
КонецФункции

Функция НовыйКлючНазначения(ТекущийКлюч, НачалоКлюча, КлючНаборовСвойств)
	
	Позиция = СтрНайти(ТекущийКлюч, НачалоКлюча);
	
	НовыйКлючНазначения = Неопределено;
	
	Если Позиция = 0 Тогда
		НовыйКлючНазначения = ТекущийКлюч + КлючНаборовСвойств;
	
	ИначеЕсли СтрНайти(ТекущийКлюч, КлючНаборовСвойств) = 0 Тогда
		НовыйКлючНазначения = Лев(ТекущийКлюч, Позиция - 1) + КлючНаборовСвойств
			+ Сред(ТекущийКлюч, Позиция + СтрДлина(НачалоКлюча) + 32);
	КонецЕсли;
	
	Возврат НовыйКлючНазначения;
	
КонецФункции

Функция КлючНаборовСвойств(Наборы)
	
	ИдентификаторыНаборов = Новый СписокЗначений;
	
	Для каждого ЭлементСписка Из Наборы Цикл
		ИдентификаторыНаборов.Добавить(Строка(ЭлементСписка.Значение.УникальныйИдентификатор()));
	КонецЦикла;
	
	ИдентификаторыНаборов.СортироватьПоЗначению();
	СтрокаИдентификаторов = "";
	
	Для каждого ЭлементСписка Из ИдентификаторыНаборов Цикл
		СтрокаИдентификаторов = СтрокаИдентификаторов + СтрЗаменить(ЭлементСписка.Значение, "-", "");
	КонецЦикла;
	
	Возврат ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрокаИдентификаторов);
	
КонецФункции

Функция РеквизитДоступенПоФункциональнымОпциям(ОписаниеСвойства)
	ОбъектДоступен = Истина;
	Для Каждого Тип Из ОписаниеСвойства.ТипЗначения.Типы() Цикл
		ОбъектМетаданных = Метаданные.НайтиПоТипу(Тип);
		Если ОбъектМетаданных = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		ОбъектДоступен = ОбщегоНазначения.ОбъектМетаданныхДоступенПоФункциональнымОпциям(ОбъектМетаданных);
		Если ОбъектДоступен Тогда
			Прервать; // Если хоть один тип доступен, то реквизит не скрывается.
		КонецЕсли;
	КонецЦикла;
	
	Возврат ОбъектДоступен;
КонецФункции

Функция ИспользуютсяСвойства(Форма, ДополнительныеПараметры)
	
	Если Не ПравоДоступа("Чтение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений) Тогда
		ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
		Возврат Ложь;
	КонецЕсли;
	
	Если ДополнительныеПараметры <> Неопределено
		И ДополнительныеПараметры.Свойство("ПроизвольныйОбъект")
		И ДополнительныеПараметры.ПроизвольныйОбъект Тогда
		Возврат Истина;
	КонецЕсли;
	
	Если ДополнительныеПараметры <> Неопределено
		И ДополнительныеПараметры.Свойство("Объект") Тогда
		ОписаниеОбъекта = ДополнительныеПараметры.Объект;
	Иначе
		ОписаниеОбъекта = Форма.Объект;
	КонецЕсли;
	ТипОбъекта = ТипЗнч(ОписаниеОбъекта.Ссылка);
	
	МетаданныеОбъекта = Метаданные.НайтиПоТипу(ТипОбъекта);
	ТабличнаяЧасть = МетаданныеОбъекта.ТабличныеЧасти.Найти("ДополнительныеРеквизиты");
	Если ТабличнаяЧасть = Неопределено Тогда
		ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
		Возврат Ложь;
	КонецЕсли;
	
	Если ОбщегоНазначения.ВидОбъектаПоТипу(ТипОбъекта) = "Справочник" Тогда
		Если Не МетаданныеОбъекта.Иерархический
			Или МетаданныеОбъекта.ВидИерархии <> Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
			ЭтоГруппа = Ложь;
		ИначеЕсли ОписаниеОбъекта.Свойство("ЭтоГруппа") Тогда
			ЭтоГруппа = ОписаниеОбъекта.ЭтоГруппа;
		ИначеЕсли ЗначениеЗаполнено(ОписаниеОбъекта.Ссылка) Тогда
			ЭтоГруппа = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОписаниеОбъекта.Ссылка, "ЭтоГруппа");
		Иначе
			ЭтоГруппа = Ложь;
		КонецЕсли;
		
		Если ЭтоГруппа И ТабличнаяЧасть.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляЭлемента
			Или Не ЭтоГруппа И ТабличнаяЧасть.Использование = Метаданные.СвойстваОбъектов.ИспользованиеРеквизита.ДляГруппы Тогда
			ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
			Возврат Ложь;
		КонецЕсли;
	КонецЕсли;
	
	ПолноеИмя = МетаданныеОбъекта.ПолноеИмя();
	
	МассивИмениФормы = СтрРазделить(ПолноеИмя, ".");
	
	ИмяЭлемента = МассивИмениФормы[0] + "_" + МассивИмениФормы[1];
	НаборСвойств = НаборСвойствПоИмени(ИмяЭлемента);
	Если НаборСвойств = Неопределено Тогда
		НаборСвойств = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяЭлемента];
	КонецЕсли;
	
	ИспользуютсяСвойства = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(НаборСвойств, "Используется");
	
	Если Не ИспользуютсяСвойства Тогда
		ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры);
	КонецЕсли;
	
	Возврат ИспользуютсяСвойства;
	
КонецФункции

Процедура ОтключитьДополнительныеРеквизитыНаФорме(Форма, ДополнительныеПараметры)
	
	МассивРеквизитов = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(
		Новый РеквизитФормы("Свойства_ИспользоватьСвойства", Новый ОписаниеТипов("Булево")));
	ПараметрыСвойствДобавлены = Ложь;
	
	СтруктураПроверки = Новый Структура("ПараметрыСвойств", "Проверка");
	ЗаполнитьЗначенияСвойств(СтруктураПроверки, Форма);
	Если СтруктураПроверки.ПараметрыСвойств <> "Проверка" Тогда
		ПараметрыСвойствДобавлены = Истина;
	КонецЕсли;
	
	Если ТипЗнч(ДополнительныеПараметры) = Тип("Структура") Тогда
		Если ДополнительныеПараметры.Свойство("ИмяЭлементаДляРазмещения") Тогда
			Если ТипЗнч(ДополнительныеПараметры.ИмяЭлементаДляРазмещения) = Тип("СписокЗначений") Тогда
				Для Каждого ЭлементСписка Из ДополнительныеПараметры.ИмяЭлементаДляРазмещения Цикл
					Форма.Элементы[ЭлементСписка.Представление].Видимость = Ложь;
				КонецЦикла;
			Иначе
				Форма.Элементы[ДополнительныеПараметры.ИмяЭлементаДляРазмещения].Видимость = Ложь;
			КонецЕсли;
		КонецЕсли;
		
		Если ДополнительныеПараметры.Свойство("ОтложеннаяИнициализация") И Не ПараметрыСвойствДобавлены Тогда
			РеквизитПараметрыСвойств = Новый РеквизитФормы("ПараметрыСвойств", Новый ОписаниеТипов());
			МассивРеквизитов.Добавить(РеквизитПараметрыСвойств);
			ПараметрыСвойствДобавлены = Истина;
		КонецЕсли;
	КонецЕсли;
	
	Форма.ИзменитьРеквизиты(МассивРеквизитов);
	Форма.Свойства_ИспользоватьСвойства = Ложь;
	Если ПараметрыСвойствДобавлены Тогда
		Форма.ПараметрыСвойств = Новый Структура;
		Форма.ПараметрыСвойств.Вставить("ВыполненаОтложеннаяИнициализация", Истина);
	КонецЕсли;
	
КонецПроцедуры

Функция ПредставлениеЗначения(Значение, КодЯзыка, ФорматСвойства)
	
	Если Значение = Неопределено Тогда
		Возврат Значение;
	КонецЕсли;
	
	Если ТипЗнч(Значение) = Тип("Строка") Тогда
		Представление = Значение;
	ИначеЕсли ТипЗнч(Значение) = Тип("Булево")
		Или ТипЗнч(Значение) = Тип("Дата")
		Или ТипЗнч(Значение) = Тип("Число") Тогда
		Если ЗначениеЗаполнено(ФорматСвойства) Тогда
			Если СтрНайти(ФорматСвойства, "Л=''") > 0 Тогда
				ФорматСвойства = СтрЗаменить(ФорматСвойства, "Л=''", "Л=" + КодЯзыка);
			ИначеЕсли СтрНайти(ФорматСвойства, "Л=") = 0 Тогда
				ФорматСвойства = "Л=" + КодЯзыка + ";" + ФорматСвойства;
			КонецЕсли;
			Представление = Формат(Значение, ФорматСвойства);
		Иначе
			Представление = Формат(Значение, "Л=" + КодЯзыка);
		КонецЕсли;
	Иначе
		Представление = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Значение, "Наименование", , КодЯзыка);
	КонецЕсли;
	
	Возврат Представление;
	
КонецФункции

Функция ФорматСвойств(Свойство)
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Свойство", Свойство);
	Запрос.Текст =
		"ВЫБРАТЬ
		|	ДополнительныеРеквизитыИСведения.ФорматСвойства КАК ФорматСвойства,
		|	ДополнительныеРеквизитыИСведения.Ссылка КАК Свойство
		|ИЗ
		|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
		|ГДЕ
		|	ДополнительныеРеквизитыИСведения.Имя В(&Свойство)
		|	ИЛИ ДополнительныеРеквизитыИСведения.Ссылка В(&Свойство)";
	
	Результат = Запрос.Выполнить().Выгрузить();
	Если Результат.Количество() = 0 Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ФорматСвойств = Новый Соответствие;
	Для Каждого Строка Из Результат Цикл
		ФорматСвойств.Вставить(Строка.Свойство, Строка.ФорматСвойства);
	КонецЦикла;
	
	Возврат ФорматСвойств;
	
КонецФункции

Процедура УстановитьВидимостьМеток(Форма, ИмяЭлементаДляРазмещенияМеток)
	
	Если Не ЗначениеЗаполнено(ИмяЭлементаДляРазмещенияМеток) Тогда
		Возврат;
	КонецЕсли;
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
	 ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		ВидимостьМеток = Ложь;
	Иначе
		ВидимостьМеток = Истина;
	КонецЕсли;
	
	Форма.Элементы[ИмяЭлементаДляРазмещенияМеток].Видимость = ВидимостьМеток;
	
КонецПроцедуры

Функция КартинкаМеткиПоЦвету(ЦветСвойств)
	
	Если ЦветСвойств = Перечисления.ЦветаСвойств.Голубой Тогда
		Картинка = БиблиотекаКартинок.МеткаГолубая;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Желтый Тогда
		Картинка = БиблиотекаКартинок.МеткаЖелтая;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Зеленый Тогда
		Картинка = БиблиотекаКартинок.МеткаЗеленая;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Лаймовый Тогда
		Картинка = БиблиотекаКартинок.МеткаЛаймовая;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Красный Тогда
		Картинка = БиблиотекаКартинок.МеткаКрасная;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Оранжевый Тогда
		Картинка = БиблиотекаКартинок.МеткаОранжевая;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Розовый Тогда
		Картинка = БиблиотекаКартинок.МеткаРозовая;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Синий Тогда
		Картинка = БиблиотекаКартинок.МеткаСиняя;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Фиолетовый Тогда
		Картинка = БиблиотекаКартинок.МеткаФиолетовая;
	Иначе
		Картинка = БиблиотекаКартинок.МеткаСерая;
	КонецЕсли;
	
	Возврат Картинка;
	
КонецФункции

Функция ЭлементСтиляПоЦвету(ЦветСвойств)
	
	Если ЦветСвойств = Перечисления.ЦветаСвойств.Лаймовый Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиЛаймовый.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Красный Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиКрасный.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Оранжевый Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиОранжевый.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Желтый Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиЖелтый.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Зеленый Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиЗеленый.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Синий Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиСиний.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Голубой Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиГолубой.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Фиолетовый Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиФиолетовый.Значение;
	ИначеЕсли ЦветСвойств = Перечисления.ЦветаСвойств.Розовый Тогда
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиРозовый.Значение;
	Иначе
		ЭлементСтиля = Метаданные.ЭлементыСтиля.ЦветМеткиСерый.Значение;
	КонецЕсли;
	
	Возврат ЭлементСтиля;
	
КонецФункции

#КонецОбласти
